Repository: ansible/ansible-modules-core

Issue:
service module broken by installation of systemd on ubuntu
##### Issue Type: Bug Report
##### Ansible Version: ansible 1.7.2+dfsg-1 (utopic package)
##### Environment: Ubuntu Utopic (14.10, currently beta) amd64, both, simple install (bash, ssh-keys, ...)
##### Summary:

If you install the `systemd` package on Ubuntu (Utopic / 14.10), the service module stops working:
##### Steps To Reproduce:

```
$ ansible test-foo -m service -a 'name=redis-server state=stopped enabled=no'

test-foo | FAILED >> {
    "failed": true, 
    "msg": "failure 1 running systemctl show for 'redis-server.service': Failed to get D-Bus connection: No connection to service manager.\n"
}
```
##### Expected Results:

It believes that, just because `systemctl` is on the path, and there's a file named `/lib/systemd/system/redis-server.service`, that the `redis-server` package is managed by `systemd`.  However, the system is using `upstart` for service management, and I believe Ubuntu will be doing so for a long time.

Ironically, `systemd` is installed because `upstart` recommends it:

```
$ dpkg -S $(which systemctl)
systemd: /bin/systemctl
$ aptitude why systemd
i   libdbus-1-3    Recommends dbus                    
i A dbus           Recommends libpam-systemd          
i A libpam-systemd Depends    systemd (= 208-8ubuntu7)
$ aptitude why libdbus-1-3
i   upstart-bin Depends libdbus-1-3 (>= 1.2.16)
$ apt-cache show upstart | fgrep -m 1 Prior
Priority: required
```

Perhaps checking `systemctl` actually works could work?

```
$ systemctl 2>/dev/null || echo "not working"
not working
```

Maybe check what `init` is?

```
% grep -o 'init=[^ ]*' /proc/cmdline || readlink -f /sbin/init
/sbin/upstart
```

I don't have any systems with working `systemd` so I can't say what else might work.



Discussion:
Hey,

I am unable to reproduce your issue, I installed ubuntu 14.10 x64, with ssh-server, nothing else. My ansible host is Centos7 with ansible 1.7.2, my target was ubuntu 14.10.

I used the following playbook

---
- name: Install systemd
  apt: name=systemd state=latest
- name: Install server-redis
  apt: name=redis-server state=latest
- name: Restart redis-server
  service: name=redis-server state=restarted

# 

ansible-playbook -i hosts systemd.yml 

PLAY [systemd test] **********************************************************\* 

GATHERING FACTS **************************************************************\* 
ok: [ubuntu1410.soh.re]

TASK: [systemd | Install systemd] ********************************************\* 
ok: [ubuntu1410.soh.re]

TASK: [systemd | Install server-redis] ***************************************\* 
ok: [ubuntu1410.soh.re]

TASK: [systemd | Restart redis-server] ***************************************\* 
changed: [ubuntu1410.soh.re]

PLAY RECAP *******************************************************************\* 
ubuntu1410.soh.re          : ok=4    changed=1    unreachable=0    failed=0   

Looks like it's only the `enabled=no` parameter, it indeed works fine for just restarting (which I probably knew, had I bothered to look at the `handlers/` instead of just the `tasks/`).

Reproduction:

```
ubuntu@wolf ~$ lxc-create -t download -n jmain -- -d ubuntu -r utopic -a amd64
Using image from local cache
Unpacking the rootfs

---
You just created an Ubuntu container (release=utopic, arch=amd64, variant=default)
The default username/password is: ubuntu / ubuntu
To gain root privileges, please use sudo.

ubuntu@wolf ~$ lxc-start -d -n jmain
```

```
ubuntu@wolf ~$ ssh jmain
ubuntu@jmain's password: 
Welcome to...
ubuntu@jmain:~$ sudo apt-get update
[sudo] password for ubuntu: 
Ign http://archive.ubuntu.com utopic InRelease
...
ubuntu@jmain:~$ sudo apt-get install python
Reading package lists... Done
...
```

```
ubuntu@wolf ~$ ssh-copy-id jmain
/usr/bin/ssh-copy-id: INFO: attempting...
..
```

```
ubuntu@wolf ~$ cat jmain
jmain

ubuntu@wolf ~$ cat jmain.yml 
- hosts: all
  tasks:
  - name: Install systemd
    apt: name=systemd state=latest
    sudo: yes

  - name: Install server-redis
    apt: name=redis-server state=latest
    sudo: yes

  - name: Restart redis-server
    service: name=redis-server state=stopped enabled=no
    sudo: yes
```

```
ubuntu@wolf ~$ ansible-playbook -i jmain -s -K jmain.yml
sudo password: 

PLAY [all] ******************************************************************** 

GATHERING FACTS *************************************************************** 
ok: [jmain]

TASK: [Install systemd] ******************************************************* 
changed: [jmain]

TASK: [Install server-redis] ************************************************** 
changed: [jmain]

TASK: [Restart redis-server] ************************************************** 
failed: [jmain] => {"failed": true}
msg: failure 1 running systemctl show for 'redis-server.service': Failed to get D-Bus connection: No connection to service manager.


FATAL: all hosts have already failed -- aborting

PLAY RECAP ******************************************************************** 
           to retry, use: --limit @/home/ubuntu/jmain.retry

jmain                      : ok=3    changed=2    unreachable=0    failed=1   

ubuntu@wolf ~$ 
```

Same problem, different services (bind,ssh,ntp), and "enabled=yes", control machine is a mac, client is running utopic.  Running ansible from git checkout, today:

failed: [MY_CLIENT] => {"failed": true}
msg: failure 1 running systemctl show for 'ssh.service': Failed to get D-Bus connection: No connection to service manager.  

state=   works fine, but enabled=   is broken.

Confirmed broken using the very latest service from devel.
Target server is Ubuntu 14.10

```
---

- name: Install systemd
  apt: name=systemd state=latest

- name: Install server-redis
  apt: name=redis-server state=latest

- name: Restart redis-server
  service: name=redis-server state=restarted enabled=no
```

```
PLAY [systemd test] *********************************************************** 

GATHERING FACTS *************************************************************** 
ok: [ubuntu1410.soh.re]

TASK: [systemd | Install systemd] ********************************************* 
ok: [ubuntu1410.soh.re]

TASK: [systemd | Install server-redis] **************************************** 
ok: [ubuntu1410.soh.re]

TASK: [systemd | Restart redis-server] **************************************** 
failed: [ubuntu1410.soh.re] => {"failed": true}
msg: failure 1 running systemctl show for 'redis-server.service': Failed to get D-Bus connection: No connection to service manager.


FATAL: all hosts have already failed -- aborting

PLAY RECAP ******************************************************************** 
           to retry, use: --limit @/root/systemd.retry

ubuntu1410.soh.re          : ok=3    changed=0    unreachable=0    failed=1   
```

Used @FauxFaux  suggestions to create PR https://github.com/ansible/ansible-modules-core/pull/232 which fixed my test hosts, targets centos7 and ubuntu1410.

Is there a workaround?

Yes, I wrote a fix, #232 is the fix, we just need Ansible to merge the code. In the meantime, you can grab this code.

I would call that a fix not a workaround :)

On Wed Nov 05 2014 at 11:20:06 PM Jonathan Mainguy notifications@github.com
wrote:

> Yes, I wrote a fix, #232
> https://github.com/ansible/ansible-modules-core/pull/232 is the fix, we
> just need Ansible to merge the code. In the meantime, you can grab this
> code.
> 
> ## 
> 
> Reply to this email directly or view it on GitHub
> https://github.com/ansible/ansible-modules-core/issues/161#issuecomment-61925711
> .


Resolving patch:
diff --git a/system/service.py b/system/service.py
--- a/system/service.py
+++ b/system/service.py
@@ -394,8 +394,24 @@ def get_service_tools(self):
             location[binary] = self.module.get_bin_path(binary)
 
         def check_systemd(name):
-            # verify service is managed by systemd
-            if not location.get('systemctl', None):
+            # verify systemd is installed (by finding systemctl)
+            if not location.get('systemctl', False):
+                return False
+
+            systemd_enabled = False
+            # Check if init is the systemd command, using comm as cmdline could be symlink
+            try:
+                f = open('/proc/1/comm', 'r')
+            except IOError, err:
+                # If comm doesn't exist, old kernel, no systemd
+                return False
+
+            for line in f:
+                if 'systemd' in line:
+                    systemd_enabled = True
+                    break
+
+            if not systemd_enabled:
                 return False
 
             # default to .service if the unit type is not specified


Test patch: