Powershell LWRP, returns attribute, and idempotency


#1

Ohai!

I’m trying to catch exit codes from my powershell code block to determine
whether my provider has affected change (to correctly set
updated_by_last_action).

I think I should be able to do this using the “returns” attribute of the
Powershell LWRP, but I’m having trouble getting it to work (and I haven’t
found many good examples). I can see the “returns” attribute should be
either an Array or Integer of acceptable exit codes, and I’ve set it to my
expected values.

However, no matter what my code block returns, Chef gets an exit code of
"1" for all non-zero return codes from Mixlib::ShellOut::ShellCommandFailed.

Here’s my sample recipe, and chef-client run error:

Even if I successfully get a non-one error code response, how do I access
this return code?

I’m hoping I’m just using it wrong. Anybody have an example?

Bryan


#2

On Wednesday, May 15, 2013 at 9:13 AM, Bryan Stenson wrote:

Ohai!

I’m trying to catch exit codes from my powershell code block to determine whether my provider has affected change (to correctly set updated_by_last_action).

I think I should be able to do this using the “returns” attribute of the Powershell LWRP, but I’m having trouble getting it to work (and I haven’t found many good examples). I can see the “returns” attribute should be either an Array or Integer of acceptable exit codes, and I’ve set it to my expected values.

However, no matter what my code block returns, Chef gets an exit code of “1” for all non-zero return codes from Mixlib::ShellOut::ShellCommandFailed.

Here’s my sample recipe, and chef-client run error: https://gist.github.com/stensonb/5585093

Even if I successfully get a non-one error code response, how do I access this return code?

I’m hoping I’m just using it wrong. Anybody have an example?

Bryan

Chef’s design makes it difficult to get data about what happens in a provider back out to a resource, so your LWRP is better off using the powershell library code directly.

https://github.com/opscode-cookbooks/powershell/blob/master/libraries/powershell_out.rb

I don’t have any experience using it so I can’t say what the issue with exit codes might be.


Daniel DeLeo


#3

This is a quirk about how the powershell provider wraps the powershell commands in a temporary ps1 file and then calls that ps1 file via the execute resource. What mixlib-shellout ends up getting back from that is essentially the $? powershell variable which is true or false and not the exit code. You can see that this is happening in this line:

C:\Windows\sysnative\WindowsPowershell\v1.0\powershell.exe
-NoLogo -NonInteractive -NoProfile -ExecutionPolicy RemoteSigned -InputFormat No
ne -Command “C:\Users\bryans\AppData\Local\Temp\2\chef-script20130515-3228-kvs9u
h.ps1”

If you were to run that in cmd.exe and looked at %errorlevel% you would see you get returned 1 because the script quit with a non-zero return code.

However if you were to do:

C:\Windows\sysnative\WindowsPowershell\v1.0\powershell.exe
-NoLogo -NonInteractive -NoProfile -ExecutionPolicy RemoteSigned -InputFormat No
ne -Command “exit 42”

You would see that %errorlevel% is 42 or the actual exit code.

If you are trying to key off of the return code in your LWRP to drive behavior of your LWRP (last updated, do something else, etc) then I would also recommend, as Daniel points out, to use the powershell_out mixin that came in v 1.0.8 of the powershell cookbook. This puts you in the context of the powershell shell itself and therefore would let you get the exit status from your process.

The code would look something like this…

Note: Put a depends “powershell” in your metadata, assuming you already have this since you are using the provider

include Chef::Mixin::PowershellOut
cmd = powershell_out(“exit 42”)
if cmd.exitstatus == 42

Do something interesting

end

Multi-line example

include Chef::Mixin::PowershellOut
script =<<-EOH
Write-Host "Nothing Interesting"
Exit 42
EOH
cmd = powershell_out(script)
if cmd.exitstatus == 42

Do something interesting

end

You can also get to cmd.stderr and cmd.stdout just like you can in shell_out. You also can pass any of the options hash just like you can in shell_out, simply add a that hash of options as the second parameter to the powershell_out method call. The allowed options are the same as in shell_out as they are just passed along down the pipe to it.

Thanks

Kevin

From: Daniel DeLeo <dan@kallistec.commailto:dan@kallistec.com>
Reply-To: "chef@lists.opscode.commailto:chef@lists.opscode.com" <chef@lists.opscode.commailto:chef@lists.opscode.com>
Date: Wednesday, May 15, 2013 10:06 AM
To: "chef@lists.opscode.commailto:chef@lists.opscode.com" <chef@lists.opscode.commailto:chef@lists.opscode.com>
Subject: [chef] Re: Powershell LWRP, returns attribute, and idempotency

On Wednesday, May 15, 2013 at 9:13 AM, Bryan Stenson wrote:

Ohai!

I’m trying to catch exit codes from my powershell code block to determine whether my provider has affected change (to correctly set updated_by_last_action).

I think I should be able to do this using the “returns” attribute of the Powershell LWRP, but I’m having trouble getting it to work (and I haven’t found many good examples). I can see the “returns” attribute should be either an Array or Integer of acceptable exit codes, and I’ve set it to my expected values.

However, no matter what my code block returns, Chef gets an exit code of “1” for all non-zero return codes from Mixlib::ShellOut::ShellCommandFailed.

Here’s my sample recipe, and chef-client run error: https://gist.github.com/stensonb/5585093

Even if I successfully get a non-one error code response, how do I access this return code?

I’m hoping I’m just using it wrong. Anybody have an example?

Bryan

Chef’s design makes it difficult to get data about what happens in a provider back out to a resource, so your LWRP is better off using the powershell library code directly.

https://github.com/opscode-cookbooks/powershell/blob/master/libraries/powershell_out.rb

I don’t have any experience using it so I can’t say what the issue with exit codes might be.


Daniel DeLeo


#4

EXCELLENT! I was just diving into what the powershell provider was
actually doing when I got your email.

Thanks for your guidance here. I really appreciate it. I hope to pay this
forward at some point.

Bryan

On Wed, May 15, 2013 at 6:11 PM, Moser, Kevin Kevin.Moser@nordstrom.comwrote:

This is a quirk about how the powershell provider wraps the powershell
commands in a temporary ps1 file and then calls that ps1 file via the
execute resource. What mixlib-shellout ends up getting back from that is
essentially the $? powershell variable which is true or false and not the
exit code. You can see that this is happening in this line:

C:\Windows\sysnative\WindowsPowershell\v1.0\powershell.exe
-NoLogo -NonInteractive -NoProfile -ExecutionPolicy RemoteSigned
-InputFormat No
ne -Command
"C:\Users\bryans\AppData\Local\Temp\2\chef-script20130515-3228-kvs9u
h.ps1"

If you were to run that in cmd.exe and looked at %errorlevel% you would
see you get returned 1 because the script quit with a non-zero return code.

However if you were to do:

C:\Windows\sysnative\WindowsPowershell\v1.0\powershell.exe
-NoLogo -NonInteractive -NoProfile -ExecutionPolicy RemoteSigned
-InputFormat No
ne -Command “exit 42”

You would see that %errorlevel% is 42 or the actual exit code.

If you are trying to key off of the return code in your LWRP to drive
behavior of your LWRP (last updated, do something else, etc) then I would
also recommend, as Daniel points out, to use the powershell_out mixin that
came in v 1.0.8 of the powershell cookbook. This puts you in the context
of the powershell shell itself and therefore would let you get the exit
status from your process.

The code would look something like this…

Note: Put a depends “powershell” in your metadata, assuming you already
have this since you are using the provider

include Chef::Mixin::PowershellOut
cmd = powershell_out(“exit 42”)
if cmd.exitstatus == 42

Do something interesting

end

Multi-line example

include Chef::Mixin::PowershellOut
script =<<-EOH
Write-Host "Nothing Interesting"
Exit 42
EOH
cmd = powershell_out(script)
if cmd.exitstatus == 42

Do something interesting

end

You can also get to cmd.stderr and cmd.stdout just like you can in
shell_out. You also can pass any of the options hash just like you can in
shell_out, simply add a that hash of options as the second parameter to the
powershell_out method call. The allowed options are the same as in
shell_out as they are just passed along down the pipe to it.

Thanks

Kevin

From: Daniel DeLeo <dan@kallistec.commailto:dan@kallistec.com>
Reply-To: "chef@lists.opscode.commailto:chef@lists.opscode.com" <
chef@lists.opscode.commailto:chef@lists.opscode.com>
Date: Wednesday, May 15, 2013 10:06 AM
To: "chef@lists.opscode.commailto:chef@lists.opscode.com" <
chef@lists.opscode.commailto:chef@lists.opscode.com>
Subject: [chef] Re: Powershell LWRP, returns attribute, and idempotency

On Wednesday, May 15, 2013 at 9:13 AM, Bryan Stenson wrote:

Ohai!

I’m trying to catch exit codes from my powershell code block to determine
whether my provider has affected change (to correctly set
updated_by_last_action).

I think I should be able to do this using the “returns” attribute of the
Powershell LWRP, but I’m having trouble getting it to work (and I haven’t
found many good examples). I can see the “returns” attribute should be
either an Array or Integer of acceptable exit codes, and I’ve set it to my
expected values.

However, no matter what my code block returns, Chef gets an exit code of
"1" for all non-zero return codes from Mixlib::ShellOut::ShellCommandFailed.

Here’s my sample recipe, and chef-client run error:
https://gist.github.com/stensonb/5585093

Even if I successfully get a non-one error code response, how do I access
this return code?

I’m hoping I’m just using it wrong. Anybody have an example?

Bryan

Chef’s design makes it difficult to get data about what happens in a
provider back out to a resource, so your LWRP is better off using the
powershell library code directly.

https://github.com/opscode-cookbooks/powershell/blob/master/libraries/powershell_out.rb

I don’t have any experience using it so I can’t say what the issue with
exit codes might be.


Daniel DeLeo