Service reload translates to restart by standard_services

58 views
Skip to first unread message

Christoffer Frost

unread,
Nov 24, 2016, 9:26:16 AM11/24/16
to help-cfengine
So I am experiencing some odd behavior by the services module standard_services, and i can't seem to find it reported before.

It seems that the default service_method body translate a "reload" command to "restart" before sending it to the service_bundle . 
This seems to only affect the default service_method body as I've tested with a custom one, as shown below:

# cat test_services.cf
bundle agent main {
  services:
    "service"
     service_policy => "reload";

    "service_test"
     service_policy => "reload",
     service_method => service_test;
}

body service_method service_test {
  service_bundle => non_standard_services("$(this.promiser)","$(this.service_policy)");
}

bundle agent non_standard_services(service,state) {
  reports:
     "Test non_standard_services promise for \"$(service)\" -> $(state)";
}

bundle agent standard_services(service,state){
  reports:
     "Test standard_service promise for \"$(service)\" -> $(state)";
}


# cf-agent -KIf ./test_services.cf
R: Test standard_service promise for "service" -> restart
R: Test non_standard_services promise for "service_test" -> reload

This occurs on version 3.7.1 on both CentOS 6 & 7. 

I assume this isn't expected behavior.


/Christoffer Frost

Marco Marongiu

unread,
Nov 26, 2016, 11:18:38 AM11/26/16
to help-c...@googlegroups.com


On 24/11/2016 15:26, Christoffer Frost wrote:
> This occurs on version 3.7.1 on both CentOS 6 & 7.

I'm not a CentOS junkie :-) so please excuse the rather naive question:
do CentOS 6/7 use System V or systemd?

Ciao
-- bronto

Marco Marongiu

unread,
Nov 27, 2016, 5:58:52 AM11/27/16
to help-c...@googlegroups.com
I should have read your message better yesterday, especially the examples.

I had a similar problem and I *think* that you are right: when you
invoke a services promise the agent does some magic behind the scenes,
translating your request into something else.

I had a problem on a system with systemd that needs some context before
the explanation. In systemd enabling/disabling a service and
starting/stopping a service are two different things:

- to start/stop a service means... well, you want that service to be
running or not to;

- to enable/disable a service means that it must/must not be started at
boot.

Now, the fact that you want a service *not* to be started at boot
doesn't mean that you don't want that service to run _at all_. E.g.: I
have my ssh server disabled, but I may want to activate it by hand some
time (e.g. to copy some files using scp or rsync) and then stop it again.

Now that it's hopefully clear what's the difference between disable and
stop: the problem I had with CFEngine was that if I used a services
promise to disable sshd, the agent would also stop it. And if I started
it afterwards, the agent would stop it again.

In an attempt to fix the problem I extrapolated the systemd specific
code from standard_services and wrote a new bundle, also "disconnecting"
additional interactions between enable/disable and start/stop actions
that are in the bundle code. It still didn't work in services promises
though, but it worked when I called the bundle alone as a methods promise.

There I understood that when you request a "disable" via a services
promise, the agent translates into a "stop" internally (or something,
now it's a few weeks I've done that and I can't remember exactly) and
passes the translated action on to the bundle.

I didn't want to use more time fighting it or diving deeper, so I just
switched to the other option: applying a methods promise instead of a
services.

Notice that running the standard_services bundle directly as a methods
promise is not against the logic. The documentation of the bundle itself
says (at least in 3.7):

> # Note you do **not** have to call this bundle from `services`
> # promises. You can simply make a `methods` call to it. That would
> # enable you to use systemd states like `try-restart` for instance.

Please do try that and let us know if it works. Thanks.

Ciao!
-- bronto

Marco Marongiu

unread,
Nov 27, 2016, 6:07:56 AM11/27/16
to help-c...@googlegroups.com


On 27/11/2016 11:58, Marco Marongiu wrote:
> Notice that running the standard_services bundle directly as a methods
> promise is not against the logic. The documentation of the bundle itself
> says (at least in 3.7):
>
>> # Note you do **not** have to call this bundle from `services`
>> # promises. You can simply make a `methods` call to it. That would
>> # enable you to use systemd states like `try-restart` for instance.

https://docs.cfengine.com/lts/reference-standard-library-services.html#standard_services

Christoffer Frost

unread,
Nov 30, 2016, 3:47:29 AM11/30/16
to help-c...@googlegroups.com
Hi Bronto.

I assume that all this logic should be handled by the standard_services bundle itself. 
But as you mention yourself it seems that some magic translation happens internally, 
while it shouldn't. This is for sure a bug. 

What version are you using ? I'll try to make a bug report of it.

Also i tested the case when using methods instead. 

bundle agent main {
  services:
    "service"
     service_policy => "reload";

    "service_test"
     service_policy => "reload",
     service_method => service_test;

  methods:
    "" usebundle => standard_services("service_method", "reload");
    "" usebundle => non_standard_services("service_test_method", "reload");
}

body service_method service_test {
  service_bundle => non_standard_services("$(this.promiser)","$(this.service_policy)");
}

bundle agent non_standard_services(service,state) {
  reports:
     "Test non_standard_services promise for \"$(service)\" -> $(state)";
}

bundle agent standard_services(service,state){
  reports:
     "Test standard_service promise for \"$(service)\" -> $(state)";
}
# cf-agent -KIf ./test_services.cf
R: Test standard_service promise for "service_method" -> reload
R: Test non_standard_services promise for "service_test_method" -> reload
R: Test standard_service promise for "service" -> restart
R: Test non_standard_services promise for "service_test" -> reload

And result is as expected. So the internal magic is definitely a bug.

/Christoffer
Reply all
Reply to author
Forward
0 new messages