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 <servicename>"
only_if 'sc query <servicename> | 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:
Sent: Monday, January 12, 2015 9:59 AM
To:
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 <
" target="_blank">
> 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