Repository: ansible/ansible

Issue:
Service restart on Solaris 10 broken
##### ISSUE TYPE
 - Bug Report

##### COMPONENT NAME
service module

##### ANSIBLE VERSION
```
ansible 2.2.1.0 (detached HEAD d8c9b8d347) last updated 2017/01/10 10:52:47 (GMT +200)
  lib/ansible/modules/core: (detached HEAD a9d844c089) last updated 2017/01/10 11:01:04 (GMT +200)
  lib/ansible/modules/extras: (detached HEAD 19d20ca1a0) last updated 2017/01/10 11:01:04 (GMT +200)
```

##### OS / ENVIRONMENT
Running from macOS 10.12
Managing Solaris 10 10/09 s10s_u8wos_08a SPARC

##### SUMMARY
Service states restarted and reloaded raise an error

##### STEPS TO REPRODUCE
```
ansible solaris10-host -m service -a "state=restarted name=system-log" -u root

```

##### EXPECTED RESULTS
Service system-log is restarted

##### ACTUAL RESULTS
```
solaris10-host | FAILED! => {
    "changed": false, 
    "failed": true, 
    "msg": "svcadm: Pattern '-s' doesn't match any instances\n"
}
```

The changes introduced with https://github.com/ansible/ansible-modules-core/pull/5406 broke compability to Solaris 10.
On Solaris 10 there is no option "-s" for subcommands restart and refresh:
Only the subcommands enable and disable support  option "-s".
man page Solaris 10: https://docs.oracle.com/cd/E23823_01/html/816-5166/svcadm-1m.html
man page Solaris 11: https://docs.oracle.com/cd/E53394_01/html/E54764/svcadm-1m.html

So for Solaris 10 this option should be omitted for restart and refresh.

We need something like 
```
if distribution_version == 10:
  option = ""
else:
  option = " -s"
[...]
 elif self.action == 'reload':
            subcmd = "refresh" + option
 elif self.action == 'restart' and status == 'online':
            subcmd = "restart" + option
```
I don't know if the service module can get distribution_version from facts.py...


Discussion:
FWIW this is also affecting SmartOS instances:
```
fatal: [haproxy]: FAILED! => {
    "changed": false, 
    "failed": true, 
    "invocation": {
        "module_args": {
            "arguments": "", 
            "enabled": null, 
            "name": "rsyslog", 
            "pattern": null, 
            "runlevel": "default", 
            "sleep": null, 
            "state": "reloaded"
        }
    }, 
    "msg": "svcadm: Pattern '-s' doesn't match any instances\n"
}
```
Same problem here.

As a work-around it is possible to put two tasks in a playbook:

    service: name=ipfilter state=stopped
    service: name=ipfilter state=started

We can use `platform.version()`; I'll submit a PR shortly.

Resolving patch:
diff --git a/lib/ansible/modules/system/service.py b/lib/ansible/modules/system/service.py
--- a/lib/ansible/modules/system/service.py
+++ b/lib/ansible/modules/system/service.py
@@ -1303,6 +1303,19 @@ def get_service_tools(self):
         if not self.svcadm_cmd:
             self.module.fail_json(msg='unable to find svcadm binary')
 
+        if self.svcadm_supports_sync():
+            self.svcadm_sync = '-s'
+        else:
+            self.svcadm_sync = ''
+
+    def svcadm_supports_sync(self):
+        # Support for synchronous restart/refresh is only supported on
+        # Oracle Solaris >= 11.
+        for line in open('/etc/release', 'r').readlines():
+            m = re.match('\s+Oracle Solaris (\d+\.\d+).*', line.rstrip())
+            if m and m.groups()[0] > 10:
+                return True
+
     def get_service_status(self):
         status = self.get_sunos_svcs_status()
         # Only 'online' is considered properly running. Everything else is off
@@ -1394,9 +1407,9 @@ def service_control(self):
         elif self.action == 'stop':
             subcmd = "disable -st"
         elif self.action == 'reload':
-            subcmd = "refresh -s"
+            subcmd = "refresh %s" % (self.svcadm_sync)
         elif self.action == 'restart' and status == 'online':
-            subcmd = "restart -s"
+            subcmd = "restart %s" % (self.svcadm_sync)
         elif self.action == 'restart' and status != 'online':
             subcmd = "enable -rst"
 


Test patch: