LWRPs and rolling back


#1

HI all,

I am writting my own LWRP for my server. So I have the following actions:

actions :stop, :db_backup, :update, :validate, :db_rollback,
:server_rollback, :start

creating the resource/provider is working pretty well. I am wondering though
how I can express the workflow logic in the recipe to roll-back only if the
validation fails.

I see some possibilities with handlers, or with the only_if/not_if
properties, notifiers/subscribers but none of them scream out as the way to
go. Are there any suggestions on best practices here?

cheers,

Florian


#2

On 10/09/13 09:32, Florian Hehlen wrote:

HI all,

I am writting my own LWRP for my server. So I have the following actions:

actions :stop, :db_backup, :update, :validate, :db_rollback,
:server_rollback, :start

creating the resource/provider is working pretty well. I am wondering
though how I can express the workflow logic in the recipe to roll-back
only if the validation fails.

I see some possibilities with handlers, or with the only_if/not_if
properties, notifiers/subscribers but none of them scream out as the
way to go. Are there any suggestions on best practices here?

cheers,

Florian

Let the provider handle the sequencing. So, in your example,I’d define
methods in the provider for each of the steps you currently have as
actions, and then in the actual actions, call them in the right order:

action :stop do
doStop
end

action :backup do
doStop
doBackup
end

action :update do
doUpdate
doRollback unless doValidate
end

action :rollback do
doRollback
end

action :validate do
doValidate
end

action :start do
doStart
end

I don’t actually know the rules of your workflow, so those may not be
right. In fact, if there are things in your workflow you’d really never
do separately from other things, then I wouldn’t even expose those as
separate actions.

Greg


#3

Greg,

Thanks for the quick response. The main thing is that I want to be able to
call :rollback only if :validation fails or in a couple of other places
where fatal errors can occur and just stopping is not good enough.

Cheers,

Florian

From: Greg Symons [mailto:gsymons@drillinginfo.com]
Sent: 09 October 2013 19:12
To: chef@lists.opscode.com
Subject: [chef] Re: LWRPs and rolling back

On 10/09/13 09:32, Florian Hehlen wrote:

HI all,

I am writting my own LWRP for my server. So I have the following actions:

actions :stop, :db_backup, :update, :validate, :db_rollback,
:server_rollback, :start

creating the resource/provider is working pretty well. I am wondering though
how I can express the workflow logic in the recipe to roll-back only if the
validation fails.

I see some possibilities with handlers, or with the only_if/not_if
properties, notifiers/subscribers but none of them scream out as the way to
go. Are there any suggestions on best practices here?

cheers,

Florian

Let the provider handle the sequencing. So, in your example, I’d define
methods in the provider for each of the steps you currently have as actions,
and then in the actual actions, call them in the right order:

action :stop do
doStop
end

action :backup do
doStop
doBackup
end

action :update do
doUpdate
doRollback unless doValidate
end

action :rollback do
doRollback
end

action :validate do
doValidate
end

action :start do
doStart
end

I don’t actually know the rules of your workflow, so those may not be right.
In fact, if there are things in your workflow you’d really never do
separately from other things, then I wouldn’t even expose those as separate
actions.

Greg


#4

You may want to rescue your actions in your provider and not expose an action :rollback. You could set a resource attribute that enables rollback capability.

On Oct 9, 2013, at 10:22 AM, “Florian Hehlen” florian.hehlen@gmail.com wrote:

Greg,

Thanks for the quick response. The main thing is that I want to be able to call :rollback only if :validation fails or in a couple of other places where fatal errors can occur and just stopping is not good enough.

Cheers,
Florian

From: Greg Symons [mailto:gsymons@drillinginfo.com]
Sent: 09 October 2013 19:12
To: chef@lists.opscode.com
Subject: [chef] Re: LWRPs and rolling back

On 10/09/13 09:32, Florian Hehlen wrote:
HI all,

I am writting my own LWRP for my server. So I have the following actions:

actions :stop, :db_backup, :update, :validate, :db_rollback, :server_rollback, :start

creating the resource/provider is working pretty well. I am wondering though how I can express the workflow logic in the recipe to roll-back only if the validation fails.

I see some possibilities with handlers, or with the only_if/not_if properties, notifiers/subscribers but none of them scream out as the way to go. Are there any suggestions on best practices here?

cheers,
Florian
Let the provider handle the sequencing. So, in your example, I’d define methods in the provider for each of the steps you currently have as actions, and then in the actual actions, call them in the right order:

action :stop do
doStop
end

action :backup do
doStop
doBackup
end

action :update do
doUpdate
doRollback unless doValidate
end

action :rollback do
doRollback
end

action :validate do
doValidate
end

action :start do
doStart
end

I don’t actually know the rules of your workflow, so those may not be right. In fact, if there are things in your workflow you’d really never do separately from other things, then I wouldn’t even expose those as separate actions.

Greg


#5

Others have commented that it may be best to keep the workflow within
the provider.

If you truly need to do workflow within the recipe, it will be a bit
awkward to express. Resource notifications are performed on success,
not on failure. To fire the rollback on failure, you’d have to do
something like the following:

foo_validated = false

ruby_block "foo_validated" do
   action :nothing
   block do
     foo_validated = true
   end
end

my_resource "foo validate" do
   name "foo-1"
   action :validate
   notifies :create, "ruby_block[foo_validated]", :immediately
   ignore_failure true
end

my_resource "foo rollback" do
   name "foo-1"
   action :rollback
   not_if { foo_validated }
end

Cheers,
Dan

On 13-10-09 10:22 AM, Florian Hehlen wrote:

Greg,

Thanks for the quick response. The main thing is that I want to be
able to call :rollback only if :validation fails or in a couple of
other places where fatal errors can occur and just stopping is not
good enough.

Cheers,

Florian

*From:*Greg Symons [mailto:gsymons@drillinginfo.com]
Sent: 09 October 2013 19:12
To: chef@lists.opscode.com
Subject: [chef] Re: LWRPs and rolling back

On 10/09/13 09:32, Florian Hehlen wrote:

HI all,

I am writting my own LWRP for my server. So I have the following
actions:

actions :stop, :db_backup, :update, :validate, :db_rollback,
:server_rollback, :start

creating the resource/provider is working pretty well. I am
wondering though how I can express the workflow logic in the
recipe to roll-back only if the validation fails.

I see some possibilities with handlers, or with the only_if/not_if
properties, notifiers/subscribers but none of them scream out as
the way to go. Are there any suggestions on best practices here?

cheers,

Florian

Let the provider handle the sequencing. So, in your example, I’d
define methods in the provider for each of the steps you currently
have as actions, and then in the actual actions, call them in the
right order:

action :stop do
doStop
end

action :backup do
doStop
doBackup
end

action :update do
doUpdate
doRollback unless doValidate
end

action :rollback do
doRollback
end

action :validate do
doValidate
end

action :start do
doStart
end

I don’t actually know the rules of your workflow, so those may not be
right. In fact, if there are things in your workflow you’d really
never do separately from other things, then I wouldn’t even expose
those as separate actions.

Greg


#6

Thanks for all the help. It clarified things eventhough I came up with an
alternate solution. I ended up going a hybrid/different way which in the end
I think provides better encapsulation than the 2 suggestions provided:

Default.rb

 include_recipe 'app::upgrade'

 include_recipe 'app::validate'

upgrade.rb

:stop

:db_backup

:configure

:update

:start

validate.rb

 :validate

rollback.rb

 :stop

 :db_rollback

 :server_rollback

 :start

 :validate

The one missing bit of the puzzle is that I use the following code in the
:validate action to call the rollback if necessary

if doRollback then

recipe_eval do

run_context.include_recipe(“app::rollback”)

end

end

I find this makes my code orthogonal and testable and also keeps the recipes
clean of any messy ruby blocks. I also added a flag to the :validate action
so that I can disable rollback call. This avoids ending up in an infinit
loop since I run validate at the end of rollback. The reason for this is
that validate also logs validation results which are good to have

cheers,

Florian

From: Dan Razzell [mailto:danr@activestate.com]
Sent: 09 October 2013 20:38
To: chef@lists.opscode.com
Subject: [chef] Re: RE: Re: LWRPs and rolling back

Others have commented that it may be best to keep the workflow within the
provider.

If you truly need to do workflow within the recipe, it will be a bit awkward
to express. Resource notifications are performed on success, not on
failure. To fire the rollback on failure, you’d have to do something like
the following:

foo_validated = false

ruby_block “foo_validated” do
action :nothing
block do
foo_validated = true
end
end

my_resource “foo validate” do
name "foo-1"
action :validate
notifies :create, “ruby_block[foo_validated]”, :immediately
ignore_failure true
end

my_resource “foo rollback” do
name "foo-1"
action :rollback
not_if { foo_validated }
end

Cheers,
Dan

On 13-10-09 10:22 AM, Florian Hehlen wrote:

Greg,

Thanks for the quick response. The main thing is that I want to be able to
call :rollback only if :validation fails or in a couple of other places
where fatal errors can occur and just stopping is not good enough.

Cheers,

Florian

From: Greg Symons [mailto:gsymons@drillinginfo.com]
Sent: 09 October 2013 19:12
To: chef@lists.opscode.com
Subject: [chef] Re: LWRPs and rolling back

On 10/09/13 09:32, Florian Hehlen wrote:

HI all,

I am writting my own LWRP for my server. So I have the following actions:

actions :stop, :db_backup, :update, :validate, :db_rollback,
:server_rollback, :start

creating the resource/provider is working pretty well. I am wondering though
how I can express the workflow logic in the recipe to roll-back only if the
validation fails.

I see some possibilities with handlers, or with the only_if/not_if
properties, notifiers/subscribers but none of them scream out as the way to
go. Are there any suggestions on best practices here?

cheers,

Florian

Let the provider handle the sequencing. So, in your example, I’d define
methods in the provider for each of the steps you currently have as actions,
and then in the actual actions, call them in the right order:

action :stop do
doStop
end

action :backup do
doStop
doBackup
end

action :update do
doUpdate
doRollback unless doValidate
end

action :rollback do
doRollback
end

action :validate do
doValidate
end

action :start do
doStart
end

I don’t actually know the rules of your workflow, so those may not be right.
In fact, if there are things in your workflow you’d really never do
separately from other things, then I wouldn’t even expose those as separate
actions.

Greg