Detect if a service is running?


#1

Hi chefs,

I’m pretty new to chef, and feel like I’m missing something obvious. Any advice would be appreciated. I’m trying to cover two scenarios with one recipe, in a Windows environment. What I’m trying to do is:

  •      Scenario 1: install a package
    
  •      Scenario 2: if the package is already installed, stop a service and then reinstall the package.
    

The recipe, as currently written, goes through a series of steps involving downloading the installer, always attempting to stop the service, then running the installer if the package is not already installed, then starting the service.

The problem I’m facing is in scenario 1. If I attempt to stop the service, but the service is not installed, then I receive an exception and execution of the recipe halts.

Am I trying to do something that is better covered by two recipes? Or is there some easy way to check if a service is installed?

Thanks

James


#2

On Friday, January 9, 2015 at 3:31 PM, James Harrison wrote:

Hi chefs,

I’m pretty new to chef, and feel like I’m missing something obvious. Any advice would be appreciated. I’m trying to cover two scenarios with one recipe, in a Windows environment. What I’m trying to do is:

  • Scenario 1: install a package
  • Scenario 2: if the package is already installed, stop a service and then reinstall the package.

The recipe, as currently written, goes through a series of steps involving downloading the installer, always attempting to stop the service, then running the installer if the package is not already installed, then starting the service.

The problem I’m facing is in scenario 1. If I attempt to stop the service, but the service is not installed, then I receive an exception and execution of the recipe halts.

Am I trying to do something that is better covered by two recipes? Or is there some easy way to check if a service is installed?

Thanks

James

A few things here. Firstly, our platform abstraction code is generally pretty tightly coupled to providers, which are also responsible for providing idempotent behavior, why-run support, logging events, and all sorts of things not related to, say, talking to the service manager or package manager. Which means that Chef doesn’t provide a nice abstract way of querying these things. So to meet your requirement to check if a package or service is installed, you’re best off running the command yourself.

As for how you accomplish that, there are a few ways. In the other branch of this thread, it was suggested to use notifies, but Chef doesn’t provide a “before notification,” which is what you’d need to stop the service before the package is upgraded (but only if it’s going to be upgraded). So one way or another, you’re going to have to write some code that can tell you if the package is about to be upgraded and will stop the service if that check returns true. You can use shell_out (specifics about doing this depend on whether you’re on Chef 11 or 12) to run a command and give you the return code and output. Once you have that, it might be as simple as adding a resource like:

service “stop FOO service before upgrading” do

other important stuff

action :stop
only_if { about_to_upgrade_package_foo? } # Ruby convention: true/false methods named w/ question mark
end

resources to install/upgrade package, start service

HTH,


Daniel DeLeo


#3

Any chance the installer has a switch to remove previous versions of
itself, if they are present?

On Mon, Jan 12, 2015 at 8:45 AM, Daniel DeLeo dan@kallistec.com wrote:

On Friday, January 9, 2015 at 3:31 PM, James Harrison wrote:

Hi chefs,

I’m pretty new to chef, and feel like I’m missing something obvious. Any
advice would be appreciated. I’m trying to cover two scenarios with one
recipe, in a Windows environment. What I’m trying to do is:

  • Scenario 1: install a package
  • Scenario 2: if the package is already installed, stop a service and
    then reinstall the package.

The recipe, as currently written, goes through a series of steps
involving downloading the installer, always attempting to stop the service,
then running the installer if the package is not already installed, then
starting the service.

The problem I’m facing is in scenario 1. If I attempt to stop the
service, but the service is not installed, then I receive an exception and
execution of the recipe halts.

Am I trying to do something that is better covered by two recipes? Or is
there some easy way to check if a service is installed?

Thanks

James

A few things here. Firstly, our platform abstraction code is generally
pretty tightly coupled to providers, which are also responsible for
providing idempotent behavior, why-run support, logging events, and all
sorts of things not related to, say, talking to the service manager or
package manager. Which means that Chef doesn’t provide a nice abstract way
of querying these things. So to meet your requirement to check if a package
or service is installed, you’re best off running the command yourself.

As for how you accomplish that, there are a few ways. In the other branch
of this thread, it was suggested to use notifies, but Chef doesn’t
provide a “before notification,” which is what you’d need to stop the
service before the package is upgraded (but only if it’s going to be
upgraded). So one way or another, you’re going to have to write some code
that can tell you if the package is about to be upgraded and will stop the
service if that check returns true. You can use shell_out (specifics
about doing this depend on whether you’re on Chef 11 or 12) to run a
command and give you the return code and output. Once you have that, it
might be as simple as adding a resource like:

service “stop FOO service before upgrading” do

other important stuff

action :stop
only_if { about_to_upgrade_package_foo? } # Ruby convention: true/false
methods named w/ question mark
end

resources to install/upgrade package, start service

HTH,


Daniel DeLeo

Kenneth Barry
TuneIn | Build and Release Engineer
M: 409-673-0544
www.tunein.com


#4

Hey chefs,

The installer will automatically uninstall previous versions of itself, but the service that the installer provides has to be stopped before the installer can proceed.

To wrap this one up, the solution I went with was a little custom code:

execute “Stop the Service” do
command "net stop "
only_if 'sc query | find “RUNNING”'
end

There are three conditions this meets:
- if the service is not installed, do not try to stop it
- if the service is installed, but stopped, do not try to stop it
- if the service is installed, and running, stop it.

The reason these three are the conditions I’m trying to meet is mostly from experimenting and finding out the failure conditions in chef. If I try to stop a non-installed service, Chef errors out. If I try to stop a service that is already stopped, Chef errors out.

sc can query quite happily whether a service exists, but if you use it to try and stop a service you get bit by a subtle piece of behavior: it’s asynchronous. As such, the command to request the service to stop will return immediately and then the service stops in the background. If you want a synchronous stopping of the service, you’ve got to use the net suite of commands.

Best

James
From: Kenneth Barry [mailto:kbarry@tunein.com]
Sent: Monday, January 12, 2015 9:59 AM
To: chef@lists.opscode.com
Subject: [chef] Re: Re: detect if a service is running?

Any chance the installer has a switch to remove previous versions of itself, if they are present?

On Mon, Jan 12, 2015 at 8:45 AM, Daniel DeLeo <dan@kallistec.commailto:dan@kallistec.com> wrote:

On Friday, January 9, 2015 at 3:31 PM, James Harrison wrote:

Hi chefs,

I’m pretty new to chef, and feel like I’m missing something obvious. Any advice would be appreciated. I’m trying to cover two scenarios with one recipe, in a Windows environment. What I’m trying to do is:

  • Scenario 1: install a package
  • Scenario 2: if the package is already installed, stop a service and then reinstall the package.

The recipe, as currently written, goes through a series of steps involving downloading the installer, always attempting to stop the service, then running the installer if the package is not already installed, then starting the service.

The problem I’m facing is in scenario 1. If I attempt to stop the service, but the service is not installed, then I receive an exception and execution of the recipe halts.

Am I trying to do something that is better covered by two recipes? Or is there some easy way to check if a service is installed?

Thanks

James

A few things here. Firstly, our platform abstraction code is generally pretty tightly coupled to providers, which are also responsible for providing idempotent behavior, why-run support, logging events, and all sorts of things not related to, say, talking to the service manager or package manager. Which means that Chef doesn’t provide a nice abstract way of querying these things. So to meet your requirement to check if a package or service is installed, you’re best off running the command yourself.

As for how you accomplish that, there are a few ways. In the other branch of this thread, it was suggested to use notifies, but Chef doesn’t provide a “before notification,” which is what you’d need to stop the service before the package is upgraded (but only if it’s going to be upgraded). So one way or another, you’re going to have to write some code that can tell you if the package is about to be upgraded and will stop the service if that check returns true. You can use shell_out (specifics about doing this depend on whether you’re on Chef 11 or 12) to run a command and give you the return code and output. Once you have that, it might be as simple as adding a resource like:

service “stop FOO service before upgrading” do

other important stuff

action :stop
only_if { about_to_upgrade_package_foo? } # Ruby convention: true/false methods named w/ question mark
end

resources to install/upgrade package, start service

HTH,


Daniel DeLeo

Kenneth Barry
TuneIn | Build and Release Engineer
M: 409-673-0544
www.tunein.comhttp://www.tunein.com/
[Image removed by sender.]


#5

Hey James,

Just a question on your workflow… do you only run Chef when you have to upgrade the service? If you are running Chef in the background (like say every 30 minutes), how will your service respond to being stopped and reinstalled regularly?

Depending on what your workflow for using the chef-client is, you may want to approach this a bit differently. Perhaps storing the target version in a data bag and conditionally running a recipe that will stop the service (if it exists) and then do the install), but if you are already running the target version it skips it?

Steve

Steven Murawski
Community Software Development Engineer @ Chef
Microsoft MVP - PowerShell
http://stevenmurawski.com

On January 12, 2015 at 3:33:10 PM, James Harrison (jharrison@alteryx.com) wrote:

Hey chefs,

The installer will automatically uninstall previous versions of itself, but the service that the installer provides has to be stopped before the installer can proceed.

To wrap this one up, the solution I went with was a little custom code:

execute “Stop the Service” do

command "net stop "

only_if ‘sc query | find “RUNNING”’

end

There are three conditions this meets:

- if the service is not installed, do not try to stop it

- if the service is installed, but stopped, do not try to stop it

- if the service is installed, and running, stop it.

The reason these three are the conditions I’m trying to meet is mostly from experimenting and finding out the failure conditions in chef. If I try to stop a non-installed service, Chef errors out. If I try to stop a service that is already stopped, Chef errors out.

sc can query quite happily whether a service exists, but if you use it to try and stop a service you get bit by a subtle piece of behavior: it’s asynchronous. As such, the command to request the service to stop will return immediately and then the service stops in the background. If you want a synchronous stopping of the service, you’ve got to use the net suite of commands.

Best

James

From: Kenneth Barry [mailto:kbarry@tunein.com]
Sent: Monday, January 12, 2015 9:59 AM
To: chef@lists.opscode.com
Subject: [chef] Re: Re: detect if a service is running?

Any chance the installer has a switch to remove previous versions of itself, if they are present?

On Mon, Jan 12, 2015 at 8:45 AM, Daniel DeLeo dan@kallistec.com wrote:

On Friday, January 9, 2015 at 3:31 PM, James Harrison wrote:

Hi chefs,

I’m pretty new to chef, and feel like I’m missing something obvious. Any advice would be appreciated. I’m trying to cover two scenarios with one recipe, in a Windows environment. What I’m trying to do is:

  • Scenario 1: install a package
  • Scenario 2: if the package is already installed, stop a service and then reinstall the package.

The recipe, as currently written, goes through a series of steps involving downloading the installer, always attempting to stop the service, then running the installer if the package is not already installed, then starting the service.

The problem I’m facing is in scenario 1. If I attempt to stop the service, but the service is not installed, then I receive an exception and execution of the recipe halts.

Am I trying to do something that is better covered by two recipes? Or is there some easy way to check if a service is installed?

Thanks

James

A few things here. Firstly, our platform abstraction code is generally pretty tightly coupled to providers, which are also responsible for providing idempotent behavior, why-run support, logging events, and all sorts of things not related to, say, talking to the service manager or package manager. Which means that Chef doesn’t provide a nice abstract way of querying these things. So to meet your requirement to check if a package or service is installed, you’re best off running the command yourself.

As for how you accomplish that, there are a few ways. In the other branch of this thread, it was suggested to use notifies, but Chef doesn’t provide a “before notification,” which is what you’d need to stop the service before the package is upgraded (but only if it’s going to be upgraded). So one way or another, you’re going to have to write some code that can tell you if the package is about to be upgraded and will stop the service if that check returns true. You can use shell_out (specifics about doing this depend on whether you’re on Chef 11 or 12) to run a command and give you the return code and output. Once you have that, it might be as simple as adding a resource like:

service “stop FOO service before upgrading” do

other important stuff

action :stop
only_if { about_to_upgrade_package_foo? } # Ruby convention: true/false methods named w/ question mark
end

resources to install/upgrade package, start service

HTH,


Daniel DeLeo

Kenneth Barry
TuneIn | Build and Release Engineer

M: 409-673-0544

www.tunein.com


#6

All that stuff being said… in real life you can usually get away with :

package “whatever” do
action :upgrade
notifies, :restart 'service[whatever]'
end

service ‘whatever’ do
action [:enable, :start]
end

Very rarely do you need to stop a service before writing the new bits to
disk, since services are typically all the way into ram. The only reason
you’d need to do this is if the service is actively reading files off disk
that the package is responsible for.

package “whatever” do
action :upgrade
notifies, :run 'bash[an_script]'
notifies, :restart 'service[whatever]'
end

bash ‘an_script’ do
code <<EOF

EOF
action :nothing
end

service ‘whatever’ do
action [:enable, :start]
end

On Mon, Jan 12, 2015 at 4:45 PM, Steven Murawski steven.murawski@gmail.com
wrote:

Hey James,

Just a question on your workflow… do you only run Chef when you have to
upgrade the service? If you are running Chef in the background (like say
every 30 minutes), how will your service respond to being stopped and
reinstalled regularly?

Depending on what your workflow for using the chef-client is, you may want
to approach this a bit differently. Perhaps storing the target version in
a data bag and conditionally running a recipe that will stop the service
(if it exists) and then do the install), but if you are already running the
target version it skips it?

Steve

Steven Murawski
Community Software Development Engineer @ Chef
Microsoft MVP - PowerShell
http://stevenmurawski.com

On January 12, 2015 at 3:33:10 PM, James Harrison (jharrison@alteryx.com)
wrote:

Hey chefs,

The installer will automatically uninstall previous versions of itself,
but the service that the installer provides has to be stopped before the
installer can proceed.

To wrap this one up, the solution I went with was a little custom code:

execute “Stop the Service” do

command "net stop "

only_if ‘sc query | find “RUNNING”’

end

There are three conditions this meets:

- if the service is not installed, do not try to stop it

- if the service is installed, but stopped, do not try to stop it

- if the service is installed, and running, stop it.

The reason these three are the conditions I’m trying to meet is mostly
from experimenting and finding out the failure conditions in chef. If I try
to stop a non-installed service, Chef errors out. If I try to stop a
service that is already stopped, Chef errors out.

sc can query quite happily whether a service exists, but if you use it to
try and stop a service you get bit by a subtle piece of behavior: it’s
asynchronous. As such, the command to request the service to stop will
return immediately and then the service stops in the background. If you
want a synchronous stopping of the service, you’ve got to use the net suite
of commands.

Best

James

From: Kenneth Barry [mailto:kbarry@tunein.com]
Sent: Monday, January 12, 2015 9:59 AM
To: chef@lists.opscode.com
Subject: [chef] Re: Re: detect if a service is running?

Any chance the installer has a switch to remove previous versions of
itself, if they are present?

On Mon, Jan 12, 2015 at 8:45 AM, Daniel DeLeo dan@kallistec.com wrote:

On Friday, January 9, 2015 at 3:31 PM, James Harrison wrote:

Hi chefs,

I’m pretty new to chef, and feel like I’m missing something obvious. Any
advice would be appreciated. I’m trying to cover two scenarios with one
recipe, in a Windows environment. What I’m trying to do is:

  • Scenario 1: install a package
  • Scenario 2: if the package is already installed, stop a service and
    then reinstall the package.

The recipe, as currently written, goes through a series of steps
involving downloading the installer, always attempting to stop the service,
then running the installer if the package is not already installed, then
starting the service.

The problem I’m facing is in scenario 1. If I attempt to stop the
service, but the service is not installed, then I receive an exception and
execution of the recipe halts.

Am I trying to do something that is better covered by two recipes? Or is
there some easy way to check if a service is installed?

Thanks

James

A few things here. Firstly, our platform abstraction code is generally
pretty tightly coupled to providers, which are also responsible for
providing idempotent behavior, why-run support, logging events, and all
sorts of things not related to, say, talking to the service manager or
package manager. Which means that Chef doesn’t provide a nice abstract way
of querying these things. So to meet your requirement to check if a package
or service is installed, you’re best off running the command yourself.

As for how you accomplish that, there are a few ways. In the other branch
of this thread, it was suggested to use notifies, but Chef doesn’t
provide a “before notification,” which is what you’d need to stop the
service before the package is upgraded (but only if it’s going to be
upgraded). So one way or another, you’re going to have to write some code
that can tell you if the package is about to be upgraded and will stop the
service if that check returns true. You can use shell_out (specifics
about doing this depend on whether you’re on Chef 11 or 12) to run a
command and give you the return code and output. Once you have that, it
might be as simple as adding a resource like:

service “stop FOO service before upgrading” do

other important stuff

action :stop
only_if { about_to_upgrade_package_foo? } # Ruby convention: true/false
methods named w/ question mark
end

resources to install/upgrade package, start service

HTH,


Daniel DeLeo

Kenneth Barry

TuneIn | Build and Release Engineer

M: 409-673-0544

www.tunein.com

[image: Image removed by sender.]


#7

Er… I meant to add more bits to that.

notifies, :run ‘bash[an_script]’ , :immediately
notifies, :restart ‘service[whatever]’, :delayed

On Mon, Jan 12, 2015 at 5:01 PM, Sean OMeara someara@chef.io wrote:

All that stuff being said… in real life you can usually get away with :

package “whatever” do
action :upgrade
notifies, :restart 'service[whatever]'
end

service ‘whatever’ do
action [:enable, :start]
end

Very rarely do you need to stop a service before writing the new bits to
disk, since services are typically all the way into ram. The only reason
you’d need to do this is if the service is actively reading files off disk
that the package is responsible for.

package “whatever” do
action :upgrade
notifies, :run 'bash[an_script]'
notifies, :restart 'service[whatever]'
end

bash ‘an_script’ do
code <<EOF

EOF
action :nothing
end

service ‘whatever’ do
action [:enable, :start]
end

On Mon, Jan 12, 2015 at 4:45 PM, Steven Murawski <
steven.murawski@gmail.com> wrote:

Hey James,

Just a question on your workflow… do you only run Chef when you have to
upgrade the service? If you are running Chef in the background (like say
every 30 minutes), how will your service respond to being stopped and
reinstalled regularly?

Depending on what your workflow for using the chef-client is, you may
want to approach this a bit differently. Perhaps storing the target
version in a data bag and conditionally running a recipe that will stop the
service (if it exists) and then do the install), but if you are already
running the target version it skips it?

Steve

Steven Murawski
Community Software Development Engineer @ Chef
Microsoft MVP - PowerShell
http://stevenmurawski.com

On January 12, 2015 at 3:33:10 PM, James Harrison (jharrison@alteryx.com)
wrote:

Hey chefs,

The installer will automatically uninstall previous versions of itself,
but the service that the installer provides has to be stopped before the
installer can proceed.

To wrap this one up, the solution I went with was a little custom code:

execute “Stop the Service” do

command "net stop "

only_if ‘sc query | find “RUNNING”’

end

There are three conditions this meets:

- if the service is not installed, do not try to stop it

- if the service is installed, but stopped, do not try to stop it

- if the service is installed, and running, stop it.

The reason these three are the conditions I’m trying to meet is mostly
from experimenting and finding out the failure conditions in chef. If I try
to stop a non-installed service, Chef errors out. If I try to stop a
service that is already stopped, Chef errors out.

sc can query quite happily whether a service exists, but if you use it to
try and stop a service you get bit by a subtle piece of behavior: it’s
asynchronous. As such, the command to request the service to stop will
return immediately and then the service stops in the background. If you
want a synchronous stopping of the service, you’ve got to use the net suite
of commands.

Best

James

From: Kenneth Barry [mailto:kbarry@tunein.com]
Sent: Monday, January 12, 2015 9:59 AM
To: chef@lists.opscode.com
Subject: [chef] Re: Re: detect if a service is running?

Any chance the installer has a switch to remove previous versions of
itself, if they are present?

On Mon, Jan 12, 2015 at 8:45 AM, Daniel DeLeo dan@kallistec.com wrote:

On Friday, January 9, 2015 at 3:31 PM, James Harrison wrote:

Hi chefs,

I’m pretty new to chef, and feel like I’m missing something obvious.
Any advice would be appreciated. I’m trying to cover two scenarios with one
recipe, in a Windows environment. What I’m trying to do is:

  • Scenario 1: install a package
  • Scenario 2: if the package is already installed, stop a service and
    then reinstall the package.

The recipe, as currently written, goes through a series of steps
involving downloading the installer, always attempting to stop the service,
then running the installer if the package is not already installed, then
starting the service.

The problem I’m facing is in scenario 1. If I attempt to stop the
service, but the service is not installed, then I receive an exception and
execution of the recipe halts.

Am I trying to do something that is better covered by two recipes? Or
is there some easy way to check if a service is installed?

Thanks

James

A few things here. Firstly, our platform abstraction code is generally
pretty tightly coupled to providers, which are also responsible for
providing idempotent behavior, why-run support, logging events, and all
sorts of things not related to, say, talking to the service manager or
package manager. Which means that Chef doesn’t provide a nice abstract way
of querying these things. So to meet your requirement to check if a package
or service is installed, you’re best off running the command yourself.

As for how you accomplish that, there are a few ways. In the other branch
of this thread, it was suggested to use notifies, but Chef doesn’t
provide a “before notification,” which is what you’d need to stop the
service before the package is upgraded (but only if it’s going to be
upgraded). So one way or another, you’re going to have to write some code
that can tell you if the package is about to be upgraded and will stop the
service if that check returns true. You can use shell_out (specifics
about doing this depend on whether you’re on Chef 11 or 12) to run a
command and give you the return code and output. Once you have that, it
might be as simple as adding a resource like:

service “stop FOO service before upgrading” do

other important stuff

action :stop
only_if { about_to_upgrade_package_foo? } # Ruby convention: true/false
methods named w/ question mark
end

resources to install/upgrade package, start service

HTH,


Daniel DeLeo

Kenneth Barry

TuneIn | Build and Release Engineer

M: 409-673-0544

www.tunein.com

[image: Image removed by sender.]


#8

Hey Steven,

You…make a very valid point. I hadn’t considered that. Well, darn.

Thanks for the suggestion on how to proceed. It makes sense to only execute any of this if necessary, so, yeah. Thank you.

Best

James

From: Steven Murawski [mailto:steven.murawski@gmail.com]
Sent: Monday, January 12, 2015 2:45 PM
To: James Harrison; chef@lists.opscode.com
Subject: Re: [chef] RE: Re: Re: detect if a service is running?

Hey James,

Just a question on your workflow… do you only run Chef when you have to upgrade the service? If you are running Chef in the background (like say every 30 minutes), how will your service respond to being stopped and reinstalled regularly?

Depending on what your workflow for using the chef-client is, you may want to approach this a bit differently. Perhaps storing the target version in a data bag and conditionally running a recipe that will stop the service (if it exists) and then do the install), but if you are already running the target version it skips it?

Steve

Steven Murawski
Community Software Development Engineer @ Chef
Microsoft MVP - PowerShell
http://stevenmurawski.comhttp://stevenmurawski.com/

On January 12, 2015 at 3:33:10 PM, James Harrison (jharrison@alteryx.commailto:jharrison@alteryx.com) wrote:
Hey chefs,

The installer will automatically uninstall previous versions of itself, but the service that the installer provides has to be stopped before the installer can proceed.

To wrap this one up, the solution I went with was a little custom code:

execute “Stop the Service” do
command "net stop "
only_if 'sc query | find “RUNNING”'
end

There are three conditions this meets:
- if the service is not installed, do not try to stop it
- if the service is installed, but stopped, do not try to stop it
- if the service is installed, and running, stop it.

The reason these three are the conditions I’m trying to meet is mostly from experimenting and finding out the failure conditions in chef. If I try to stop a non-installed service, Chef errors out. If I try to stop a service that is already stopped, Chef errors out.

sc can query quite happily whether a service exists, but if you use it to try and stop a service you get bit by a subtle piece of behavior: it’s asynchronous. As such, the command to request the service to stop will return immediately and then the service stops in the background. If you want a synchronous stopping of the service, you’ve got to use the net suite of commands.

Best

James
From: Kenneth Barry [mailto:kbarry@tunein.com]
Sent: Monday, January 12, 2015 9:59 AM
To: chef@lists.opscode.commailto:chef@lists.opscode.com
Subject: [chef] Re: Re: detect if a service is running?

Any chance the installer has a switch to remove previous versions of itself, if they are present?

On Mon, Jan 12, 2015 at 8:45 AM, Daniel DeLeo <dan@kallistec.commailto:dan@kallistec.com> wrote:

On Friday, January 9, 2015 at 3:31 PM, James Harrison wrote:

Hi chefs,

I’m pretty new to chef, and feel like I’m missing something obvious. Any advice would be appreciated. I’m trying to cover two scenarios with one recipe, in a Windows environment. What I’m trying to do is:

  • Scenario 1: install a package
  • Scenario 2: if the package is already installed, stop a service and then reinstall the package.

The recipe, as currently written, goes through a series of steps involving downloading the installer, always attempting to stop the service, then running the installer if the package is not already installed, then starting the service.

The problem I’m facing is in scenario 1. If I attempt to stop the service, but the service is not installed, then I receive an exception and execution of the recipe halts.

Am I trying to do something that is better covered by two recipes? Or is there some easy way to check if a service is installed?

Thanks

James
A few things here. Firstly, our platform abstraction code is generally pretty tightly coupled to providers, which are also responsible for providing idempotent behavior, why-run support, logging events, and all sorts of things not related to, say, talking to the service manager or package manager. Which means that Chef doesn’t provide a nice abstract way of querying these things. So to meet your requirement to check if a package or service is installed, you’re best off running the command yourself.

As for how you accomplish that, there are a few ways. In the other branch of this thread, it was suggested to use notifies, but Chef doesn’t provide a “before notification,” which is what you’d need to stop the service before the package is upgraded (but only if it’s going to be upgraded). So one way or another, you’re going to have to write some code that can tell you if the package is about to be upgraded and will stop the service if that check returns true. You can use shell_out (specifics about doing this depend on whether you’re on Chef 11 or 12) to run a command and give you the return code and output. Once you have that, it might be as simple as adding a resource like:

service “stop FOO service before upgrading” do

other important stuff

action :stop
only_if { about_to_upgrade_package_foo? } # Ruby convention: true/false methods named w/ question mark
end

resources to install/upgrade package, start service

HTH,


Daniel DeLeo

Kenneth Barry
TuneIn | Build and Release Engineer
M: 409-673-0544
www.tunein.comhttp://www.tunein.com/
[Image removed by sender.]


#9

Hey Sean,

That is frighteningly useful information. Even if I don’t use it for this project (and I may well use it), it’s incredibly useful to be aware that the upgrade action exists inside the package resource, and that I can notify a service restart from it.

Thank you!

James

From: Sean OMeara [mailto:someara@chef.io]
Sent: Monday, January 12, 2015 3:03 PM
To: chef@lists.opscode.com
Subject: [chef] Re: Re: RE: Re: Re: detect if a service is running?

Er… I meant to add more bits to that.

notifies, :run ‘bash[an_script]’ , :immediately
notifies, :restart ‘service[whatever]’, :delayed

On Mon, Jan 12, 2015 at 5:01 PM, Sean OMeara <someara@chef.iomailto:someara@chef.io> wrote:
All that stuff being said… in real life you can usually get away with :

package “whatever” do
action :upgrade
notifies, :restart 'service[whatever]'
end

service ‘whatever’ do
action [:enable, :start]
end

Very rarely do you need to stop a service before writing the new bits to disk, since services are typically all the way into ram. The only reason you’d need to do this is if the service is actively reading files off disk that the package is responsible for.

package “whatever” do
action :upgrade
notifies, :run 'bash[an_script]'
notifies, :restart 'service[whatever]'
end

bash ‘an_script’ do
code <<EOF

EOF
action :nothing
end

service ‘whatever’ do
action [:enable, :start]
end

On Mon, Jan 12, 2015 at 4:45 PM, Steven Murawski <steven.murawski@gmail.commailto:steven.murawski@gmail.com> wrote:
Hey James,

Just a question on your workflow… do you only run Chef when you have to upgrade the service? If you are running Chef in the background (like say every 30 minutes), how will your service respond to being stopped and reinstalled regularly?

Depending on what your workflow for using the chef-client is, you may want to approach this a bit differently. Perhaps storing the target version in a data bag and conditionally running a recipe that will stop the service (if it exists) and then do the install), but if you are already running the target version it skips it?

Steve

Steven Murawski
Community Software Development Engineer @ Chef
Microsoft MVP - PowerShell
http://stevenmurawski.comhttp://stevenmurawski.com/

On January 12, 2015 at 3:33:10 PM, James Harrison (jharrison@alteryx.commailto:jharrison@alteryx.com) wrote:
Hey chefs,

The installer will automatically uninstall previous versions of itself, but the service that the installer provides has to be stopped before the installer can proceed.

To wrap this one up, the solution I went with was a little custom code:

execute “Stop the Service” do
command "net stop "
only_if 'sc query | find “RUNNING”'
end

There are three conditions this meets:
- if the service is not installed, do not try to stop it
- if the service is installed, but stopped, do not try to stop it
- if the service is installed, and running, stop it.

The reason these three are the conditions I’m trying to meet is mostly from experimenting and finding out the failure conditions in chef. If I try to stop a non-installed service, Chef errors out. If I try to stop a service that is already stopped, Chef errors out.

sc can query quite happily whether a service exists, but if you use it to try and stop a service you get bit by a subtle piece of behavior: it’s asynchronous. As such, the command to request the service to stop will return immediately and then the service stops in the background. If you want a synchronous stopping of the service, you’ve got to use the net suite of commands.

Best

James
From: Kenneth Barry [mailto:kbarry@tunein.commailto:kbarry@tunein.com]
Sent: Monday, January 12, 2015 9:59 AM
To: chef@lists.opscode.commailto:chef@lists.opscode.com
Subject: [chef] Re: Re: detect if a service is running?

Any chance the installer has a switch to remove previous versions of itself, if they are present?

On Mon, Jan 12, 2015 at 8:45 AM, Daniel DeLeo <dan@kallistec.commailto:dan@kallistec.com> wrote:

On Friday, January 9, 2015 at 3:31 PM, James Harrison wrote:

Hi chefs,

I’m pretty new to chef, and feel like I’m missing something obvious. Any advice would be appreciated. I’m trying to cover two scenarios with one recipe, in a Windows environment. What I’m trying to do is:

  • Scenario 1: install a package
  • Scenario 2: if the package is already installed, stop a service and then reinstall the package.

The recipe, as currently written, goes through a series of steps involving downloading the installer, always attempting to stop the service, then running the installer if the package is not already installed, then starting the service.

The problem I’m facing is in scenario 1. If I attempt to stop the service, but the service is not installed, then I receive an exception and execution of the recipe halts.

Am I trying to do something that is better covered by two recipes? Or is there some easy way to check if a service is installed?

Thanks

James
A few things here. Firstly, our platform abstraction code is generally pretty tightly coupled to providers, which are also responsible for providing idempotent behavior, why-run support, logging events, and all sorts of things not related to, say, talking to the service manager or package manager. Which means that Chef doesn’t provide a nice abstract way of querying these things. So to meet your requirement to check if a package or service is installed, you’re best off running the command yourself.

As for how you accomplish that, there are a few ways. In the other branch of this thread, it was suggested to use notifies, but Chef doesn’t provide a “before notification,” which is what you’d need to stop the service before the package is upgraded (but only if it’s going to be upgraded). So one way or another, you’re going to have to write some code that can tell you if the package is about to be upgraded and will stop the service if that check returns true. You can use shell_out (specifics about doing this depend on whether you’re on Chef 11 or 12) to run a command and give you the return code and output. Once you have that, it might be as simple as adding a resource like:

service “stop FOO service before upgrading” do

other important stuff

action :stop
only_if { about_to_upgrade_package_foo? } # Ruby convention: true/false methods named w/ question mark
end

resources to install/upgrade package, start service

HTH,


Daniel DeLeo

Kenneth Barry
TuneIn | Build and Release Engineer
M: 409-673-0544tel:409-673-0544
www.tunein.comhttp://www.tunein.com/
[Image removed by sender.]


#10

Unless things have change, be aware the “package” resource can be a bit
tricky to use in windows. (This may not be relevant, as i use a quite-old
version of chef.)

On Mon, Jan 12, 2015 at 2:27 PM, James Harrison jharrison@alteryx.com
wrote:

Hey Sean,

That is frighteningly useful information. Even if I don’t use it for this
project (and I may well use it), it’s incredibly useful to be aware that
the upgrade action exists inside the package resource, and that I can
notify a service restart from it.

Thank you!

James

From: Sean OMeara [mailto:someara@chef.io]
Sent: Monday, January 12, 2015 3:03 PM
To: chef@lists.opscode.com
Subject: [chef] Re: Re: RE: Re: Re: detect if a service is running?

Er… I meant to add more bits to that.

notifies, :run ‘bash[an_script]’ , :immediately

notifies, :restart ‘service[whatever]’, :delayed

On Mon, Jan 12, 2015 at 5:01 PM, Sean OMeara someara@chef.io wrote:

All that stuff being said… in real life you can usually get away with :

package “whatever” do

action :upgrade

notifies, :restart ‘service[whatever]’

end

service ‘whatever’ do

action [:enable, :start]

end

Very rarely do you need to stop a service before writing the new bits to
disk, since services are typically all the way into ram. The only reason
you’d need to do this is if the service is actively reading files off disk
that the package is responsible for.

package “whatever” do

action :upgrade

notifies, :run ‘bash[an_script]’

notifies, :restart ‘service[whatever]’

end

bash ‘an_script’ do

code <<EOF

EOF

action :nothing

end

service ‘whatever’ do

action [:enable, :start]

end

On Mon, Jan 12, 2015 at 4:45 PM, Steven Murawski <
steven.murawski@gmail.com> wrote:

Hey James,

Just a question on your workflow… do you only run Chef when you have to
upgrade the service? If you are running Chef in the background (like say
every 30 minutes), how will your service respond to being stopped and
reinstalled regularly?

Depending on what your workflow for using the chef-client is, you may want
to approach this a bit differently. Perhaps storing the target version in
a data bag and conditionally running a recipe that will stop the service
(if it exists) and then do the install), but if you are already running the
target version it skips it?

Steve

Steven Murawski

Community Software Development Engineer @ Chef

Microsoft MVP - PowerShell
http://stevenmurawski.com

On January 12, 2015 at 3:33:10 PM, James Harrison (jharrison@alteryx.com)
wrote:

Hey chefs,

The installer will automatically uninstall previous versions of itself,
but the service that the installer provides has to be stopped before the
installer can proceed.

To wrap this one up, the solution I went with was a little custom code:

execute “Stop the Service” do

command "net stop "

only_if ‘sc query | find “RUNNING”’

end

There are three conditions this meets:

- if the service is not installed, do not try to stop it

- if the service is installed, but stopped, do not try to stop it

- if the service is installed, and running, stop it.

The reason these three are the conditions I’m trying to meet is mostly
from experimenting and finding out the failure conditions in chef. If I try
to stop a non-installed service, Chef errors out. If I try to stop a
service that is already stopped, Chef errors out.

sc can query quite happily whether a service exists, but if you use it to
try and stop a service you get bit by a subtle piece of behavior: it’s
asynchronous. As such, the command to request the service to stop will
return immediately and then the service stops in the background. If you
want a synchronous stopping of the service, you’ve got to use the net suite
of commands.

Best

James

From: Kenneth Barry [mailto:kbarry@tunein.com]
Sent: Monday, January 12, 2015 9:59 AM
To: chef@lists.opscode.com
Subject: [chef] Re: Re: detect if a service is running?

Any chance the installer has a switch to remove previous versions of
itself, if they are present?

On Mon, Jan 12, 2015 at 8:45 AM, Daniel DeLeo dan@kallistec.com wrote:

On Friday, January 9, 2015 at 3:31 PM, James Harrison wrote:

Hi chefs,

I’m pretty new to chef, and feel like I’m missing something obvious. Any
advice would be appreciated. I’m trying to cover two scenarios with one
recipe, in a Windows environment. What I’m trying to do is:

  • Scenario 1: install a package
  • Scenario 2: if the package is already installed, stop a service and
    then reinstall the package.

The recipe, as currently written, goes through a series of steps
involving downloading the installer, always attempting to stop the service,
then running the installer if the package is not already installed, then
starting the service.

The problem I’m facing is in scenario 1. If I attempt to stop the
service, but the service is not installed, then I receive an exception and
execution of the recipe halts.

Am I trying to do something that is better covered by two recipes? Or is
there some easy way to check if a service is installed?

Thanks

James

A few things here. Firstly, our platform abstraction code is generally
pretty tightly coupled to providers, which are also responsible for
providing idempotent behavior, why-run support, logging events, and all
sorts of things not related to, say, talking to the service manager or
package manager. Which means that Chef doesn’t provide a nice abstract way
of querying these things. So to meet your requirement to check if a package
or service is installed, you’re best off running the command yourself.

As for how you accomplish that, there are a few ways. In the other branch
of this thread, it was suggested to use notifies, but Chef doesn’t
provide a “before notification,” which is what you’d need to stop the
service before the package is upgraded (but only if it’s going to be
upgraded). So one way or another, you’re going to have to write some code
that can tell you if the package is about to be upgraded and will stop the
service if that check returns true. You can use shell_out (specifics
about doing this depend on whether you’re on Chef 11 or 12) to run a
command and give you the return code and output. Once you have that, it
might be as simple as adding a resource like:

service “stop FOO service before upgrading” do

other important stuff

action :stop
only_if { about_to_upgrade_package_foo? } # Ruby convention: true/false
methods named w/ question mark
end

resources to install/upgrade package, start service

HTH,


Daniel DeLeo

Kenneth Barry

TuneIn | Build and Release Engineer

M: 409-673-0544

www.tunein.com

[image: Image removed by sender.]

Kenneth Barry
TuneIn | Build and Release Engineer
M: 409-673-0544
www.tunein.com


#11

You might so something like

Use the ‘package’ resource, (you can even tell it that the installer is someplace remote), if it isn’t jnatalled, it installs the program.

To handle scenario 2, there might be an action for package to always install, even of it’s there, else, you might try a package block to remove, followed by one to install, assuming uninstall stops the service for you.

Question, if it’s installed and running, why is the reinstall necessary?

Sent from my iPhone

On Jan 9, 2015, at 3:31 PM, James Harrison jharrison@alteryx.com wrote:

Hi chefs,

I’m pretty new to chef, and feel like I’m missing something obvious. Any advice would be appreciated. I’m trying to cover two scenarios with one recipe, in a Windows environment. What I’m trying to do is:

  •      Scenario 1: install a package
    
  •      Scenario 2: if the package is already installed, stop a service and then reinstall the package.
    

The recipe, as currently written, goes through a series of steps involving downloading the installer, always attempting to stop the service, then running the installer if the package is not already installed, then starting the service.

The problem I’m facing is in scenario 1. If I attempt to stop the service, but the service is not installed, then I receive an exception and execution of the recipe halts.

Am I trying to do something that is better covered by two recipes? Or is there some easy way to check if a service is installed?

Thanks

James


#12

I just realized that he service in question might not be installed by the thing our installing.

Take a look at ‘notifies’, I think there is a was to have it restart a service when a block executes.

Sent from my iPhone

On Jan 9, 2015, at 3:31 PM, James Harrison jharrison@alteryx.com wrote:

Hi chefs,

I’m pretty new to chef, and feel like I’m missing something obvious. Any advice would be appreciated. I’m trying to cover two scenarios with one recipe, in a Windows environment. What I’m trying to do is:

  •      Scenario 1: install a package
    
  •      Scenario 2: if the package is already installed, stop a service and then reinstall the package.
    

The recipe, as currently written, goes through a series of steps involving downloading the installer, always attempting to stop the service, then running the installer if the package is not already installed, then starting the service.

The problem I’m facing is in scenario 1. If I attempt to stop the service, but the service is not installed, then I receive an exception and execution of the recipe halts.

Am I trying to do something that is better covered by two recipes? Or is there some easy way to check if a service is installed?

Thanks

James


#13

Hi James,
I had a similar problem in that performing an upgrade on our software on Windows requires the services be stopped.
As I wanted to make everything available under one application cookbook I also used custom ruby code and an LWRP.
The first part enumerates the services currently running by matching the service names to the app (like if the service names contain the string and that they are running, then build an array of them).
It then stops only the running services. It also goes into a loop on each one checking it’s state has changed to stopped before stopping the next service. It does this because some files that need updating need to be not locked by another program/service.
The upgrade then takes place and the same list used to start the services are stopped. This avoids us starting services that need to not be (we have some use cases where this is the case).

An LWRP was created to facilitate calling this library to make it simple and it works well.

Cheers
Chris

From: James Harrison [mailto:jharrison@alteryx.com]
Sent: 12 January 2015 16:25
To: chef@lists.opscode.com
Subject: [chef] RE: Re: detect if a service is running?

HI Kenneth,

Thanks for the ideas!

To answer your specific question, the reason to reinstall a package that is installed is that it’s an upgrade installation. I should have made that much clearer :slight_smile:

I’ll look into notifies, see what I can learn from it.

Thanks!

James

From: Kenneth Barry [mailto:kbarry@tunein.com]
Sent: Friday, January 09, 2015 6:11 PM
To: chef@lists.opscode.commailto:chef@lists.opscode.com
Subject: [chef] Re: detect if a service is running?

I just realized that he service in question might not be installed by the thing our installing.

Take a look at ‘notifies’, I think there is a was to have it restart a service when a block executes.

Sent from my iPhone

On Jan 9, 2015, at 3:31 PM, James Harrison <jharrison@alteryx.commailto:jharrison@alteryx.com> wrote:
Hi chefs,

I’m pretty new to chef, and feel like I’m missing something obvious. Any advice would be appreciated. I’m trying to cover two scenarios with one recipe, in a Windows environment. What I’m trying to do is:

  •      Scenario 1: install a package
    
  •      Scenario 2: if the package is already installed, stop a service and then reinstall the package.
    

The recipe, as currently written, goes through a series of steps involving downloading the installer, always attempting to stop the service, then running the installer if the package is not already installed, then starting the service.

The problem I’m facing is in scenario 1. If I attempt to stop the service, but the service is not installed, then I receive an exception and execution of the recipe halts.

Am I trying to do something that is better covered by two recipes? Or is there some easy way to check if a service is installed?

Thanks

James


#14

HI Kenneth,

Thanks for the ideas!

To answer your specific question, the reason to reinstall a package that is installed is that it’s an upgrade installation. I should have made that much clearer :slight_smile:

I’ll look into notifies, see what I can learn from it.

Thanks!

James

From: Kenneth Barry [mailto:kbarry@tunein.com]
Sent: Friday, January 09, 2015 6:11 PM
To: chef@lists.opscode.com
Subject: [chef] Re: detect if a service is running?

I just realized that he service in question might not be installed by the thing our installing.

Take a look at ‘notifies’, I think there is a was to have it restart a service when a block executes.

Sent from my iPhone

On Jan 9, 2015, at 3:31 PM, James Harrison <jharrison@alteryx.commailto:jharrison@alteryx.com> wrote:
Hi chefs,

I’m pretty new to chef, and feel like I’m missing something obvious. Any advice would be appreciated. I’m trying to cover two scenarios with one recipe, in a Windows environment. What I’m trying to do is:

  •      Scenario 1: install a package
    
  •      Scenario 2: if the package is already installed, stop a service and then reinstall the package.
    

The recipe, as currently written, goes through a series of steps involving downloading the installer, always attempting to stop the service, then running the installer if the package is not already installed, then starting the service.

The problem I’m facing is in scenario 1. If I attempt to stop the service, but the service is not installed, then I receive an exception and execution of the recipe halts.

Am I trying to do something that is better covered by two recipes? Or is there some easy way to check if a service is installed?

Thanks

James