ansiblesystemdsystemctl

Why does Ansible list a service, but with a status "not-found"?


TL;DR

What does a service status of not-found mean in Ansible's service facts?

More in detail:

With Ansible you can list all services on a host along with their states by:

ansible -m service_facts myhost

Example output:

myhost | SUCCESS => {
    "ansible_facts": {
        "services": {
            "ModemManager.service": {
                "name": "ModemManager.service",
                "source": "systemd",
                "state": "running",
                "status": "enabled"
            },
            "NetworkManager-dispatcher.service": {
                "name": "NetworkManager-dispatcher.service",
                "source": "systemd",
                "state": "inactive",
                "status": "enabled"
            },
            ...
            }
        }
    },
    "changed": false
}

So far so good, but what about this service:

"systemd-timesyncd.service": {
   "name": "systemd-timesyncd.service",
   "source": "systemd",
   "state": "stopped",
   "status": "not-found"
}            

What does the status not-found mean?

The problem arising is that I have an Ansible playbook which would disable this service. To prevent any error if the service to be stopped does not exist at all, I added a check (see when attribute):

- name: Populate service facts
  ansible.builtin.service_facts: ~

- name: Disable systemd-timesyncd service (replaced with chrony as NTP server)
  ansible.builtin.systemd:
    name: "{{ item }}"
    state: stopped
    enabled: false
  when: "item in services"
  with_items:
    - systemd-timesyncd.service
  become: true

This playbook snippet would throw an error saying "service systemd-timesyncd.service not found". So, I realized that the check is not enough. Instead, I had to replace the following:

when: "item in services"

with:

when: "(item in services) and (services[item].status != 'not-found')"

But I would like to understand why this is the case. Why are non-existing services reported (i.e., included in Ansible's "service" facts) although they are reported as not-found?

Is this an Ansible "feature"? Or does this strange behavior come from the underlying systemd?


Solution

  • Why are non-existing services reported (i.e., included in Ansible's service_facts) although they are reported as not-found? ... does this ... come from the underlying systemd?

    It seems that the Ansible service_facts module – Return service state information as fact data only performs an

    systemctl --full --type service --all
    systemctl --full --type service --all | grep not-found
    ● display-manager.service                                                                   not-found inactive dead    display-manager.service
    ● sntp.service                                                                              not-found inactive dead    sntp.service
    ● syslog.service                                                                            not-found inactive dead    syslog.service
    ● systemd-sysusers.service                                                                  not-found inactive dead    systemd-sysusers.service
    ● ypbind.service                                                                            not-found inactive dead    ypbind.service
    ● yppasswdd.service                                                                         not-found inactive dead    yppasswdd.service
    ● ypserv.service                                                                            not-found inactive dead    ypserv.service
    ● ypxfrd.service                                                                            not-found inactive dead    ypxfrd.service
    

    as one could double check via the minimal example playbook

    ---
    - hosts: localhost
      become: false
      gather_facts: false
    
      tasks:
    
      - service_facts:
    
      - debug:
          var: (ansible_facts.services).keys() | sort
    

    The reported service keys and states are (almost) the same.

    If interested in which code exactly is executed or in more depth information and details, just have a look at the source of ansible/modules/service_facts.py, line #253 and #281.

    Thanks To


    What does the status not-found mean?

    That seems to be more a question for unix.stackexchange.com or superuser.com, like in Cleaning/Debugging services

    If the unit is not-found and inactive yet stays in the list, then it's probably wanted or required by another unit. For example, the unit is probably still enabled, i.e. your /etc/systemd/system/*.target.wants contains a symlink to it.

    sudo grep -R 'systemd-timesyncd.service' /etc/systemd/system
    /etc/systemd/system/multi-user.target.wants/chronyd.service:Conflicts=ntpd.service systemd-timesyncd.service