diff options
Diffstat (limited to '')
26 files changed, 937 insertions, 0 deletions
diff --git a/test/integration/targets/service/aliases b/test/integration/targets/service/aliases new file mode 100644 index 0000000..f2f9ac9 --- /dev/null +++ b/test/integration/targets/service/aliases @@ -0,0 +1,4 @@ +destructive +shippable/posix/group1 +skip/osx +skip/macos diff --git a/test/integration/targets/service/files/ansible-broken.upstart b/test/integration/targets/service/files/ansible-broken.upstart new file mode 100644 index 0000000..4e9c669 --- /dev/null +++ b/test/integration/targets/service/files/ansible-broken.upstart @@ -0,0 +1,10 @@ +description "ansible test daemon" + +start on runlevel [345] +stop on runlevel [!345] + +expect daemon + +exec ansible_test_service + +manual diff --git a/test/integration/targets/service/files/ansible.rc b/test/integration/targets/service/files/ansible.rc new file mode 100644 index 0000000..ec77d52 --- /dev/null +++ b/test/integration/targets/service/files/ansible.rc @@ -0,0 +1,16 @@ +#!/bin/sh + +# PROVIDE: ansible_test_service +# REQUIRE: FILESYSTEMS devfs +# BEFORE: LOGIN +# KEYWORD: nojail shutdown + +. /etc/rc.subr + +name="ansible_test_service" +rcvar="ansible_test_service_enable" +command="/usr/sbin/${name}" +pidfile="/var/run/${name}.pid" +extra_commands=reload +load_rc_config $name +run_rc_command "$1" diff --git a/test/integration/targets/service/files/ansible.systemd b/test/integration/targets/service/files/ansible.systemd new file mode 100644 index 0000000..3466f25 --- /dev/null +++ b/test/integration/targets/service/files/ansible.systemd @@ -0,0 +1,11 @@ +[Unit] +Description=Ansible Test Service + +[Service] +ExecStart=/usr/sbin/ansible_test_service "Test\nthat newlines in scripts\nwork" +ExecReload=/bin/true +Type=forking +PIDFile=/var/run/ansible_test_service.pid + +[Install] +WantedBy=multi-user.target diff --git a/test/integration/targets/service/files/ansible.sysv b/test/integration/targets/service/files/ansible.sysv new file mode 100755 index 0000000..1df0423 --- /dev/null +++ b/test/integration/targets/service/files/ansible.sysv @@ -0,0 +1,134 @@ +#!/bin/sh +# + +# LSB header + +### BEGIN INIT INFO +# Provides: ansible-test +# Default-Start: 3 4 5 +# Default-Stop: 0 1 2 6 +# Short-Description: test daemon for ansible +# Description: This is a test daemon used by ansible for testing only +### END INIT INFO + +# chkconfig header + +# chkconfig: 345 99 99 +# description: This is a test daemon used by ansible for testing only +# +# processname: /usr/sbin/ansible_test_service + +# Sanity checks. +[ -x /usr/sbin/ansible_test_service ] || exit 0 + +DEBIAN_VERSION=/etc/debian_version +SUSE_RELEASE=/etc/SuSE-release +# Source function library. +if [ -f $DEBIAN_VERSION ]; then + . /lib/lsb/init-functions +elif [ -f $SUSE_RELEASE -a -r /etc/rc.status ]; then + . /etc/rc.status +else + . /etc/rc.d/init.d/functions +fi + +SERVICE=ansible_test_service +PROCESS=ansible_test_service +CONFIG_ARGS=" " +if [ -f $DEBIAN_VERSION ]; then + LOCKFILE=/var/lock/$SERVICE +else + LOCKFILE=/var/lock/subsys/$SERVICE +fi + +RETVAL=0 + +start() { + echo -n "Starting ansible test daemon: " + if [ -f $SUSE_RELEASE ]; then + startproc -p /var/run/${SERVICE}.pid -f /usr/sbin/ansible_test_service + rc_status -v + elif [ -e $DEBIAN_VERSION ]; then + if [ -f $LOCKFILE ]; then + echo -n "already started, lock file found" + RETVAL=1 + elif /usr/sbin/ansible_test_service; then + echo -n "OK" + RETVAL=0 + fi + else + daemon --check $SERVICE $PROCESS --daemonize $CONFIG_ARGS + fi + RETVAL=$? + echo + [ $RETVAL -eq 0 ] && touch $LOCKFILE + return $RETVAL +} + +stop() { + echo -n "Stopping ansible test daemon: " + if [ -f $SUSE_RELEASE ]; then + killproc -TERM /usr/sbin/ansible_test_service + rc_status -v + elif [ -f $DEBIAN_VERSION ]; then + # Added this since Debian's start-stop-daemon doesn't support spawned processes + if ps -ef | grep "/usr/sbin/ansible_test_service" | grep -v grep | awk '{print $2}' | xargs kill &> /dev/null; then + echo -n "OK" + RETVAL=0 + else + echo -n "Daemon is not started" + RETVAL=1 + fi + else + killproc -p /var/run/${SERVICE}.pid + fi + RETVAL=$? + echo + if [ $RETVAL -eq 0 ]; then + rm -f $LOCKFILE + rm -f /var/run/$SERVICE.pid + fi +} + +restart() { + stop + start +} + +# See how we were called. +case "$1" in + start|stop|restart) + $1 + ;; + status) + if [ -f $SUSE_RELEASE ]; then + echo -n "Checking for ansible test service " + checkproc /usr/sbin/ansible_test_service + rc_status -v + elif [ -f $DEBIAN_VERSION ]; then + if [ -f $LOCKFILE ]; then + RETVAL=0 + echo "ansible test is running." + else + RETVAL=1 + echo "ansible test is stopped." + fi + else + status $PROCESS + RETVAL=$? + fi + ;; + condrestart) + [ -f $LOCKFILE ] && restart || : + ;; + reload) + echo "ok" + RETVAL=0 + ;; + *) + echo "Usage: $0 {start|stop|status|restart|condrestart|reload}" + exit 1 + ;; +esac +exit $RETVAL + diff --git a/test/integration/targets/service/files/ansible.upstart b/test/integration/targets/service/files/ansible.upstart new file mode 100644 index 0000000..369f61a --- /dev/null +++ b/test/integration/targets/service/files/ansible.upstart @@ -0,0 +1,9 @@ +description "ansible test daemon" + +start on runlevel [345] +stop on runlevel [!345] + +expect daemon + +exec ansible_test_service + diff --git a/test/integration/targets/service/files/ansible_test_service.py b/test/integration/targets/service/files/ansible_test_service.py new file mode 100644 index 0000000..522493f --- /dev/null +++ b/test/integration/targets/service/files/ansible_test_service.py @@ -0,0 +1,74 @@ +#!/usr/bin/env python + +# this is mostly based off of the code found here: +# http://code.activestate.com/recipes/278731-creating-a-daemon-the-python-way/ + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + +import os +import resource +import signal +import sys +import time + +UMASK = 0 +WORKDIR = "/" +MAXFD = 1024 + +if (hasattr(os, "devnull")): + REDIRECT_TO = os.devnull +else: + REDIRECT_TO = "/dev/null" + + +def createDaemon(): + try: + pid = os.fork() + except OSError as e: + raise Exception("%s [%d]" % (e.strerror, e.errno)) + + if (pid == 0): + os.setsid() + + try: + pid = os.fork() + except OSError as e: + raise Exception("%s [%d]" % (e.strerror, e.errno)) + + if (pid == 0): + os.chdir(WORKDIR) + os.umask(UMASK) + else: + f = open('/var/run/ansible_test_service.pid', 'w') + f.write("%d\n" % pid) + f.close() + os._exit(0) + else: + os._exit(0) + + maxfd = resource.getrlimit(resource.RLIMIT_NOFILE)[1] + if (maxfd == resource.RLIM_INFINITY): + maxfd = MAXFD + + for fd in range(0, maxfd): + try: + os.close(fd) + except OSError: # ERROR, fd wasn't open to begin with (ignored) + pass + + os.open(REDIRECT_TO, os.O_RDWR) + os.dup2(0, 1) + os.dup2(0, 2) + + return (0) + + +if __name__ == "__main__": + + signal.signal(signal.SIGHUP, signal.SIG_IGN) + + retCode = createDaemon() + + while True: + time.sleep(1000) diff --git a/test/integration/targets/service/meta/main.yml b/test/integration/targets/service/meta/main.yml new file mode 100644 index 0000000..399f3fb --- /dev/null +++ b/test/integration/targets/service/meta/main.yml @@ -0,0 +1,20 @@ +# test code for the service module +# (c) 2014, James Cammarata <jcammarata@ansible.com> + +# This file is part of Ansible +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see <http://www.gnu.org/licenses/>. + +dependencies: + - prepare_tests diff --git a/test/integration/targets/service/tasks/main.yml b/test/integration/targets/service/tasks/main.yml new file mode 100644 index 0000000..4fc2ddf --- /dev/null +++ b/test/integration/targets/service/tasks/main.yml @@ -0,0 +1,62 @@ +- name: skip unsupported distros + meta: end_host + when: ansible_distribution in ['Alpine'] + +- name: install the test daemon script + copy: + src: ansible_test_service.py + dest: /usr/sbin/ansible_test_service + mode: '755' + +- name: rewrite shebang in the test daemon script + lineinfile: + path: /usr/sbin/ansible_test_service + line: "#!{{ ansible_python_interpreter | realpath }}" + insertbefore: BOF + firstmatch: yes + +- block: + # determine init system is in use + - name: detect sysv init system + set_fact: + service_type: sysv + when: + - ansible_distribution in ['RedHat', 'CentOS', 'ScientificLinux'] + - ansible_distribution_version is version('6', '>=') + - ansible_distribution_version is version('7', '<') + - name: detect systemd init system + set_fact: + service_type: systemd + when: (ansible_distribution in ['RedHat', 'CentOS', 'ScientificLinux'] and ansible_distribution_major_version is version('7', '>=')) or ansible_distribution == 'Fedora' or (ansible_distribution == 'Ubuntu' and ansible_distribution_version is version('15.04', '>=')) or (ansible_distribution == 'Debian' and ansible_distribution_version is version('8', '>=')) or ansible_os_family == 'Suse' + - name: detect upstart init system + set_fact: + service_type: upstart + when: + - ansible_distribution == 'Ubuntu' + - ansible_distribution_version is version('15.04', '<') + - name: detect rc init system + set_fact: + service_type: rc + when: + - ansible_distribution.lower().endswith('bsd') + + + - name: display value of ansible_service_mgr + debug: + msg: 'ansible_service_mgr: {{ ansible_service_mgr }}' + + - name: setup test service script + include_tasks: '{{ service_type }}_setup.yml' + + - name: execute tests + import_tasks: tests.yml + + always: + - name: disable and stop ansible test service + service: + name: ansible_test + state: stopped + enabled: false + + # cleaning up changes made by this playbook + - include_tasks: '{{ service_type }}_cleanup.yml' diff --git a/test/integration/targets/service/tasks/rc_cleanup.yml b/test/integration/targets/service/tasks/rc_cleanup.yml new file mode 100644 index 0000000..47f470c --- /dev/null +++ b/test/integration/targets/service/tasks/rc_cleanup.yml @@ -0,0 +1,9 @@ +- name: remove the rc init file + file: path=/etc/rc.d/ansible_test state=absent + register: remove_rc_result + +- name: assert that the rc init file was removed + assert: + that: + - "remove_rc_result.path == '/etc/rc.d/ansible_test'" + - "remove_rc_result.state == 'absent'" diff --git a/test/integration/targets/service/tasks/rc_setup.yml b/test/integration/targets/service/tasks/rc_setup.yml new file mode 100644 index 0000000..45d2c90 --- /dev/null +++ b/test/integration/targets/service/tasks/rc_setup.yml @@ -0,0 +1,21 @@ +- name: install the rc init file + copy: src=ansible.rc dest=/etc/rc.d/ansible_test mode=0755 + register: install_rc_result + +- name: assert that the rc init file was installed + assert: + that: + - "install_rc_result.dest == '/etc/rc.d/ansible_test'" + - "install_rc_result.state == 'file'" + - "install_rc_result.mode == '0755'" + - "install_rc_result.checksum == '8526e4571d2ac685fa5a73af723183c194bda35d'" + +# FreeBSD (likely others as well) requires the command_interpreter to match the +# shebang the script was started with as an extra caution against killing the +# wrong thing. We add the line here. +- name: add command_interpreter in rc init file + lineinfile: + path: /etc/rc.d/ansible_test + line: "command_interpreter={{ ansible_python_interpreter | realpath }}" + insertafter: '^pidfile.*' + firstmatch: yes diff --git a/test/integration/targets/service/tasks/systemd_cleanup.yml b/test/integration/targets/service/tasks/systemd_cleanup.yml new file mode 100644 index 0000000..e070726 --- /dev/null +++ b/test/integration/targets/service/tasks/systemd_cleanup.yml @@ -0,0 +1,25 @@ +- name: remove the systemd unit file + file: path=/usr/lib/systemd/system/ansible_test.service state=absent + register: remove_systemd_result + +- name: remove the systemd unit file + file: path=/usr/lib/systemd/system/ansible_test_broken.service state=absent + register: remove_systemd_broken_result + +- debug: var=remove_systemd_broken_result +- name: assert that the systemd unit file was removed + assert: + that: + - "remove_systemd_result.path == '/usr/lib/systemd/system/ansible_test.service'" + - "remove_systemd_result.state == 'absent'" + - "remove_systemd_broken_result.path == '/usr/lib/systemd/system/ansible_test_broken.service'" + - "remove_systemd_broken_result.state == 'absent'" + +- name: make sure systemd is reloaded + shell: systemctl daemon-reload + register: restart_systemd_result + +- name: assert that systemd was reloaded + assert: + that: + - "restart_systemd_result.rc == 0" diff --git a/test/integration/targets/service/tasks/systemd_setup.yml b/test/integration/targets/service/tasks/systemd_setup.yml new file mode 100644 index 0000000..a9170a3 --- /dev/null +++ b/test/integration/targets/service/tasks/systemd_setup.yml @@ -0,0 +1,17 @@ +- name: install the systemd unit file + copy: src=ansible.systemd dest=/etc/systemd/system/ansible_test.service mode=0644 + register: install_systemd_result + +- name: install a broken systemd unit file + file: src=ansible_test.service path=/etc/systemd/system/ansible_test_broken.service state=link + register: install_broken_systemd_result + +- name: assert that the systemd unit file was installed + assert: + that: + - "install_systemd_result.dest == '/etc/systemd/system/ansible_test.service'" + - "install_systemd_result.state == 'file'" + - "install_systemd_result.mode == '0644'" + - "install_systemd_result.checksum == '9e6320795a5c79c01230a6de1c343ea32097af52'" + - "install_broken_systemd_result.dest == '/etc/systemd/system/ansible_test_broken.service'" + - "install_broken_systemd_result.state == 'link'" diff --git a/test/integration/targets/service/tasks/sysv_cleanup.yml b/test/integration/targets/service/tasks/sysv_cleanup.yml new file mode 100644 index 0000000..dbdfcf8 --- /dev/null +++ b/test/integration/targets/service/tasks/sysv_cleanup.yml @@ -0,0 +1,9 @@ +- name: remove the sysV init file + file: path=/etc/init.d/ansible_test state=absent + register: remove_sysv_result + +- name: assert that the sysV init file was removed + assert: + that: + - "remove_sysv_result.path == '/etc/init.d/ansible_test'" + - "remove_sysv_result.state == 'absent'" diff --git a/test/integration/targets/service/tasks/sysv_setup.yml b/test/integration/targets/service/tasks/sysv_setup.yml new file mode 100644 index 0000000..7b648c2 --- /dev/null +++ b/test/integration/targets/service/tasks/sysv_setup.yml @@ -0,0 +1,11 @@ +- name: install the sysV init file + copy: src=ansible.sysv dest=/etc/init.d/ansible_test mode=0755 + register: install_sysv_result + +- name: assert that the sysV init file was installed + assert: + that: + - "install_sysv_result.dest == '/etc/init.d/ansible_test'" + - "install_sysv_result.state == 'file'" + - "install_sysv_result.mode == '0755'" + - "install_sysv_result.checksum == '362899814c47d9aad6e93b2f64e39edd24e38797'" diff --git a/test/integration/targets/service/tasks/tests.yml b/test/integration/targets/service/tasks/tests.yml new file mode 100644 index 0000000..cfb4215 --- /dev/null +++ b/test/integration/targets/service/tasks/tests.yml @@ -0,0 +1,258 @@ +- name: disable the ansible test service + service: name=ansible_test enabled=no + +- name: (check mode run) enable the ansible test service + service: name=ansible_test enabled=yes + register: enable_in_check_mode_result + check_mode: yes + +- name: assert that changes reported for check mode run + assert: + that: + - "enable_in_check_mode_result is changed" + +- name: (check mode run) test that service defaults are used + service: + register: enable_in_check_mode_result + check_mode: yes + module_defaults: + service: + name: ansible_test + enabled: yes + +- name: assert that changes reported for check mode run + assert: + that: + - "enable_in_check_mode_result is changed" + +- name: (check mode run) test that specific module defaults are used + service: + register: enable_in_check_mode_result + check_mode: yes + when: "ansible_service_mgr in ['sysvinit', 'systemd']" + module_defaults: + sysvinit: + name: ansible_test + enabled: yes + systemd: + name: ansible_test + enabled: yes + +- name: assert that changes reported for check mode run + assert: + that: + - "enable_in_check_mode_result is changed" + when: "ansible_service_mgr in ['sysvinit', 'systemd']" + +- name: enable the ansible test service + service: name=ansible_test enabled=yes + register: enable_result + +- name: assert that the service was enabled and changes reported + assert: + that: + - "enable_result.enabled == true" + - "enable_result is changed" + +- name: start the ansible test service + service: name=ansible_test state=started + register: start_result + +- name: assert that the service was started + assert: + that: + - "start_result.state == 'started'" + - "start_result is changed" + +- name: check that the service was started + shell: 'cat /proc/$(cat /var/run/ansible_test_service.pid)/cmdline' + register: cmdline + failed_when: cmdline is failed or '\0/usr/sbin/ansible_test_service\0' not in cmdline.stdout + # No proc on BSD + when: not ansible_distribution.lower().endswith('bsd') + +- name: check that the service was started (*bsd) + shell: 'ps -p $(cat /var/run/ansible_test_service.pid)' + register: cmdline + failed_when: cmdline is failed or '/usr/sbin/ansible_test_service' not in cmdline.stdout + when: ansible_distribution.lower().endswith('bsd') + +- name: find the service with a pattern + service: name=ansible_test pattern="ansible_test_ser" state=started + register: start2_result + +- name: assert that the service was started via the pattern + assert: + that: + - "start2_result.name == 'ansible_test'" + - "start2_result.state == 'started'" + - "start2_result is not changed" + +- name: fetch PID for ansible_test service (before restart) + command: 'cat /var/run/ansible_test_service.pid' + register: pid_before_restart + +- name: restart the ansible test service + service: name=ansible_test state=restarted + register: restart_result + +- name: assert that the service was restarted + assert: + that: + - "restart_result.state == 'started'" + - "restart_result is changed" + +- name: fetch PID for ansible_test service (after restart) + command: 'cat /var/run/ansible_test_service.pid' + register: pid_after_restart + +- name: "check that PIDs aren't the same" + fail: + when: pid_before_restart.stdout == pid_after_restart.stdout + +- name: check that service is started + command: 'cat /proc/{{ pid_after_restart.stdout }}/cmdline' + register: cmdline + failed_when: cmdline is failed or '\0/usr/sbin/ansible_test_service\0' not in cmdline.stdout + # No proc on BSD + when: not ansible_distribution.lower().endswith('bsd') + +- name: check that the service is started (*bsd) + shell: 'ps -p {{ pid_after_restart.stdout }}' + register: cmdline + failed_when: cmdline is failed or '/usr/sbin/ansible_test_service' not in cmdline.stdout + when: ansible_distribution.lower().endswith('bsd') + +- name: restart the ansible test service with a sleep + service: name=ansible_test state=restarted sleep=2 + register: restart_sleep_result + +- name: assert that the service was restarted with a sleep + assert: + that: + - "restart_sleep_result.state == 'started'" + - "restart_sleep_result is changed" + +- name: reload the ansible test service + service: name=ansible_test state=reloaded + register: reload_result + # don't do this on systems with systemd because it triggers error: + # Unable to reload service ansible_test: ansible_test.service is not active, cannot reload. + when: service_type != "systemd" + +- name: assert that the service was reloaded + assert: + that: + - "reload_result.state == 'started'" + - "reload_result is changed" + when: service_type != "systemd" + +- name: "test for #42786 (sysvinit)" + when: service_type == "sysv" + block: + - name: "sysvinit (#42786): check state, 'enable' parameter isn't set" + service: use=sysvinit name=ansible_test state=started + + - name: "sysvinit (#42786): check that service is still enabled" + service: use=sysvinit name=ansible_test enabled=yes + register: result_enabled + failed_when: result_enabled is changed + +- name: fetch PID for ansible_test service + command: 'cat /var/run/ansible_test_service.pid' + register: ansible_test_pid + +- name: check that service is started + command: 'cat /proc/{{ ansible_test_pid.stdout }}/cmdline' + register: cmdline + failed_when: cmdline is failed or '\0/usr/sbin/ansible_test_service\0' not in cmdline.stdout + # No proc on BSD + when: not ansible_distribution.lower().endswith('bsd') + +- name: check that the service is started (*bsd) + shell: 'ps -p {{ ansible_test_pid.stdout }}' + register: cmdline + failed_when: cmdline is failed or '/usr/sbin/ansible_test_service' not in cmdline.stdout + when: ansible_distribution.lower().endswith('bsd') + +- name: stop the ansible test service + service: name=ansible_test state=stopped + register: stop_result + +- name: check that the service is stopped + command: 'cat /proc/{{ ansible_test_pid.stdout }}/cmdline' + register: cmdline + failed_when: cmdline is not failed or '\0/usr/sbin/ansible_test_service\0' in cmdline.stdout + # No proc on BSD + when: not ansible_distribution.lower().endswith('bsd') + +- name: check that the service is stopped (*bsd) + shell: 'ps -p {{ ansible_test_pid.stdout }}' + register: cmdline + failed_when: cmdline is not failed or '/usr/sbin/ansible_test_service' in cmdline.stdout + when: ansible_distribution.lower().endswith('bsd') + +- name: assert that the service was stopped + assert: + that: + - "stop_result.state == 'stopped'" + - "stop_result is changed" + +- name: disable the ansible test service + service: name=ansible_test enabled=no + register: disable_result + +- name: assert that the service was disabled + assert: + that: + - "disable_result.enabled == false" + - "disable_result is changed" + +- name: try to enable a broken service + service: name=ansible_broken_test enabled=yes + register: broken_enable_result + ignore_errors: True + +- name: assert that the broken test failed + assert: + that: + - "broken_enable_result is failed" + +- name: remove the test daemon script + file: path=/usr/sbin/ansible_test_service state=absent + register: remove_result + +- name: assert that the test daemon script was removed + assert: + that: + - "remove_result.path == '/usr/sbin/ansible_test_service'" + - "remove_result.state == 'absent'" + +- name: the module must fail when a service is not found + service: + name: 'nonexisting' + state: stopped + register: result + ignore_errors: yes + when: ansible_distribution != 'FreeBSD' + +- assert: + that: + - result is failed + - result is search("Could not find the requested service nonexisting") + when: ansible_distribution != 'FreeBSD' + +- name: the module must fail in check_mode as well when a service is not found + service: + name: 'nonexisting' + state: stopped + register: result + check_mode: yes + ignore_errors: yes + when: ansible_distribution != 'FreeBSD' + +- assert: + that: + - result is failed + - result is search("Could not find the requested service nonexisting") + when: ansible_distribution != 'FreeBSD' diff --git a/test/integration/targets/service/tasks/upstart_cleanup.yml b/test/integration/targets/service/tasks/upstart_cleanup.yml new file mode 100644 index 0000000..683fb10 --- /dev/null +++ b/test/integration/targets/service/tasks/upstart_cleanup.yml @@ -0,0 +1,17 @@ +- vars: + upstart_files: + - /etc/init/ansible_test.conf + - /etc/init/ansible_test.override + - /etc/init/ansible_test_broken.conf + block: + - name: remove upstart init files + file: + path: '{{ item }}' + state: absent + loop: '{{ upstart_files }}' + + - name: assert that upstart init files were removed + raw: 'test -e {{ item }}' + loop: '{{ upstart_files }}' + register: file_exists + failed_when: file_exists is not failed diff --git a/test/integration/targets/service/tasks/upstart_setup.yml b/test/integration/targets/service/tasks/upstart_setup.yml new file mode 100644 index 0000000..e9607bb --- /dev/null +++ b/test/integration/targets/service/tasks/upstart_setup.yml @@ -0,0 +1,19 @@ +- name: install the upstart init file + copy: src=ansible.upstart dest=/etc/init/ansible_test.conf mode=0644 + register: install_upstart_result + +- name: install an upstart init file that will fail (manual in .conf) + copy: src=ansible-broken.upstart dest=/etc/init/ansible_broken_test.conf mode=0644 + register: install_upstart_broken_result + +- name: assert that the upstart init file was installed + assert: + that: + - "install_upstart_result.dest == '/etc/init/ansible_test.conf'" + - "install_upstart_result.state == 'file'" + - "install_upstart_result.mode == '0644'" + - "install_upstart_result.checksum == '5c314837b6c4dd6c68d1809653a2974e9078e02a'" + - "install_upstart_broken_result.dest == '/etc/init/ansible_broken_test.conf'" + - "install_upstart_broken_result.state == 'file'" + - "install_upstart_broken_result.mode == '0644'" + - "install_upstart_broken_result.checksum == 'e66497894f2b2bf71e1380a196cc26089cc24a10'" diff --git a/test/integration/targets/service/templates/main.yml b/test/integration/targets/service/templates/main.yml new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/integration/targets/service/templates/main.yml diff --git a/test/integration/targets/service_facts/aliases b/test/integration/targets/service_facts/aliases new file mode 100644 index 0000000..17d3eb7 --- /dev/null +++ b/test/integration/targets/service_facts/aliases @@ -0,0 +1,4 @@ +shippable/posix/group2 +skip/freebsd +skip/osx +skip/macos diff --git a/test/integration/targets/service_facts/files/ansible.systemd b/test/integration/targets/service_facts/files/ansible.systemd new file mode 100644 index 0000000..3466f25 --- /dev/null +++ b/test/integration/targets/service_facts/files/ansible.systemd @@ -0,0 +1,11 @@ +[Unit] +Description=Ansible Test Service + +[Service] +ExecStart=/usr/sbin/ansible_test_service "Test\nthat newlines in scripts\nwork" +ExecReload=/bin/true +Type=forking +PIDFile=/var/run/ansible_test_service.pid + +[Install] +WantedBy=multi-user.target diff --git a/test/integration/targets/service_facts/files/ansible_test_service.py b/test/integration/targets/service_facts/files/ansible_test_service.py new file mode 100644 index 0000000..19f1e29 --- /dev/null +++ b/test/integration/targets/service_facts/files/ansible_test_service.py @@ -0,0 +1,73 @@ +#!/usr/bin/env python + +# this is mostly based off of the code found here: +# http://code.activestate.com/recipes/278731-creating-a-daemon-the-python-way/ + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +import os +import resource +import signal +import time + +UMASK = 0 +WORKDIR = "/" +MAXFD = 1024 + +if (hasattr(os, "devnull")): + REDIRECT_TO = os.devnull +else: + REDIRECT_TO = "/dev/null" + + +def createDaemon(): + try: + pid = os.fork() + except OSError as e: + raise Exception("%s [%d]" % (e.strerror, e.errno)) + + if (pid == 0): + os.setsid() + + try: + pid = os.fork() + except OSError as e: + raise Exception("%s [%d]" % (e.strerror, e.errno)) + + if (pid == 0): + os.chdir(WORKDIR) + os.umask(UMASK) + else: + f = open('/var/run/ansible_test_service.pid', 'w') + f.write("%d\n" % pid) + f.close() + os._exit(0) + else: + os._exit(0) + + maxfd = resource.getrlimit(resource.RLIMIT_NOFILE)[1] + if (maxfd == resource.RLIM_INFINITY): + maxfd = MAXFD + + for fd in range(0, maxfd): + try: + os.close(fd) + except OSError: # ERROR, fd wasn't open to begin with (ignored) + pass + + os.open(REDIRECT_TO, os.O_RDWR) + os.dup2(0, 1) + os.dup2(0, 2) + + return (0) + + +if __name__ == "__main__": + + signal.signal(signal.SIGHUP, signal.SIG_IGN) + + retCode = createDaemon() + + while True: + time.sleep(1000) diff --git a/test/integration/targets/service_facts/tasks/main.yml b/test/integration/targets/service_facts/tasks/main.yml new file mode 100644 index 0000000..d2d6528 --- /dev/null +++ b/test/integration/targets/service_facts/tasks/main.yml @@ -0,0 +1,29 @@ +# Test playbook for the service_facts module +# Copyright: (c) 2017, Adam Miller <admiller@redhat.com> +# Copyright: (c) 2020, Abhijeet Kasurde <akasurde@redhat.com> +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +- name: skip broken distros + meta: end_host + when: ansible_distribution == 'Alpine' + +- name: Gather service facts + service_facts: + +- name: check for ansible_facts.services exists + assert: + that: ansible_facts.services is defined + +- name: Test disabled service facts (https://github.com/ansible/ansible/issues/69144) + block: + - name: display value of ansible_service_mgr + debug: + msg: 'ansible_service_mgr: {{ ansible_service_mgr }}' + + - name: setup test service script + include_tasks: 'systemd_setup.yml' + + - name: execute tests + import_tasks: tests.yml + + when: (ansible_distribution in ['RedHat', 'CentOS', 'ScientificLinux'] and ansible_distribution_major_version is version('7', '>=')) or ansible_distribution == 'Fedora' or (ansible_distribution == 'Ubuntu' and ansible_distribution_version is version('15.04', '>=')) or (ansible_distribution == 'Debian' and ansible_distribution_version is version('8', '>=')) or ansible_os_family == 'Suse' diff --git a/test/integration/targets/service_facts/tasks/systemd_cleanup.yml b/test/integration/targets/service_facts/tasks/systemd_cleanup.yml new file mode 100644 index 0000000..b68530b --- /dev/null +++ b/test/integration/targets/service_facts/tasks/systemd_cleanup.yml @@ -0,0 +1,32 @@ +- name: remove the systemd unit file + file: + path: /usr/lib/systemd/system/ansible_test.service + state: absent + register: remove_systemd_result + +- name: assert that the systemd unit file was removed + assert: + that: + - "remove_systemd_result.path == '/usr/lib/systemd/system/ansible_test.service'" + - "remove_systemd_result.state == 'absent'" + +- name: remove python systemd test script file + file: + path: /usr/sbin/ansible_test_service + state: absent + register: remove_systemd_binary_result + +- name: assert that python systemd test script file was removed + assert: + that: + - "remove_systemd_binary_result.path == '/usr/sbin/ansible_test_service'" + - "remove_systemd_binary_result.state == 'absent'" + +- name: make sure systemd is reloaded + shell: systemctl daemon-reload + register: restart_systemd_result + +- name: assert that systemd was reloaded + assert: + that: + - "restart_systemd_result.rc == 0" diff --git a/test/integration/targets/service_facts/tasks/systemd_setup.yml b/test/integration/targets/service_facts/tasks/systemd_setup.yml new file mode 100644 index 0000000..85eeed0 --- /dev/null +++ b/test/integration/targets/service_facts/tasks/systemd_setup.yml @@ -0,0 +1,26 @@ +- name: install the test daemon script + copy: + src: ansible_test_service.py + dest: /usr/sbin/ansible_test_service + mode: '755' + +- name: rewrite shebang in the test daemon script + lineinfile: + path: /usr/sbin/ansible_test_service + line: "#!{{ ansible_python_interpreter | realpath }}" + insertbefore: BOF + firstmatch: yes + +- name: install the systemd unit file + copy: + src: ansible.systemd + dest: /etc/systemd/system/ansible_test.service + mode: '0644' + register: install_systemd_result + +- name: assert that the systemd unit file was installed + assert: + that: + - "install_systemd_result.dest == '/etc/systemd/system/ansible_test.service'" + - "install_systemd_result.state == 'file'" + - "install_systemd_result.mode == '0644'" diff --git a/test/integration/targets/service_facts/tasks/tests.yml b/test/integration/targets/service_facts/tasks/tests.yml new file mode 100644 index 0000000..495b71f --- /dev/null +++ b/test/integration/targets/service_facts/tasks/tests.yml @@ -0,0 +1,36 @@ +- name: start the ansible test service + service: + name: ansible_test + enabled: yes + state: started + register: enable_result + +- name: assert that the service was enabled and changes reported + assert: + that: + - "enable_result.enabled == true" + - "enable_result is changed" + +- name: disable the ansible test service + service: + name: ansible_test + state: stopped + enabled: no + register: start_result + +- name: assert that the service was stopped + assert: + that: + - "start_result.state == 'stopped'" + - "start_result is changed" + +- name: Populate service facts + service_facts: + +- name: get ansible_test service's state + debug: + var: services['ansible_test.service'].state + +- name: ansible_test service's running state should be \"inactive\" + assert: + that: "services['ansible_test.service'].state == 'inactive'" |