Issue 1:
ISSUE TYPE

Bug Report

Feature Idea

Documentation Report

COMPONENT NAME

ANSIBLE VERSION

ansible 2.3.0.0
config file = /etc/ansible/ansible.cfg
configured module search path = Default w/o overrides
python version = 2.7.5 (default, Nov 6 2016, 00:28:07) [GCC 4.8.5 20150623 (Red Hat 4.8.5-11)]

CONFIGURATION

my ansible configured as follow:

[defaults]
gathering = smart
fact_caching_timeout = 2592000
fact_caching = redis
fact_caching_connection = localhost:6379
host_key_checking = False
[privilege_escalation]
[paramiko_connection]
[ssh_connection]
pipelining = False
[persistent_connection]
connect_timeout = 30
connect_retries = 30
connect_interval = 1
[accelerate]
[selinux]
[colors]
[diff]

OS / ENVIRONMENT

CentOS Linux release 7.2.1511 (Core)
Linux localhost.localdomain 3.10.0-327.el7.x86_64 #1 SMP Thu Nov 19 22:10:57 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux
Python 2.7.5

SUMMARY

**I use redis to cache ansible facts, but when redis's key expires, I can't use ansible-plabook to perform the host group operation, but I can use Playbook for a single host operation

also,If I cache facts early, then this playbook can be normal。

**

STEPS TO REPRODUCE

the full traceback was:

Traceback (most recent call last):
File "/usr/bin/ansible-playbook", line 109, in <module>
exit_code = cli.run()
File "/usr/lib/python2.7/site-packages/ansible/cli/playbook.py", line 154, in run
results = pbex.run()
File "/usr/lib/python2.7/site-packages/ansible/executor/playbook_executor.py", line 153, in run
result = self._tqm.run(play=play)
File "/usr/lib/python2.7/site-packages/ansible/executor/task_queue_manager.py", line 264, in run
start_at_done = self._start_at_done,
File "/usr/lib/python2.7/site-packages/ansible/executor/play_iterator.py", line 213, in __init__
if host.name in variable_manager._fact_cache and variable_manager._fact_cache.get(host.name).get('module_setup', False):
AttributeError: 'NoneType' object has no attribute 'get'

EXPECTED RESULTS

ACTUAL RESULTS

Issue 2:
ISSUE TYPE

Bug Report

COMPONENT NAME

redis.py

ANSIBLE VERSION

ansible --version
ansible 2.3.0.0
config file = /home/dkimsey/redis/ansible.cfg
configured module search path = Default w/o overrides
python version = 2.7.5 (default, Nov 20 2015, 02:00:19) [GCC 4.8.5 20150623 (Red Hat 4.8.5-4)]

CONFIGURATION

[defaults]
gathering = smart

# just demo a small amount please
gather_subset = virtual

fact_caching = redis
fact_caching_connection = localhost:6379:1
# 5s
fact_caching_timeout = 5

[privilege_escalation]
become=False

OS / ENVIRONMENT

RHEL 7/OS X

SUMMARY

The redis cache plugin will not return facts when the data expires mid-run. It raises a KeyError but that does not seem to trigger a re-gather-facts for those hosts.

The jsonfile and in-memory facts appear to return the old, expired data.

I believe the desired behavior should be a KeyError in smart mode should trigger a re-gathering of facts for those hosts.

STEPS TO REPRODUCE

Using the aforementioned ansible.cfg settings, the following playbook will demo the expiring between plays. Note if one were to use jsonfile or no-cache (in-memory?) it works correctly and maintains the data the entire run.

Playbook: demo.yml:

- hosts: localhost
connection: local
tasks:
- name: Facts gathereed OK
debug:
var: ansible_date_time.epoch
- name: Sleep for a few seconds
command: sleep 2

- hosts: localhost
connection: local
tasks:
- name: Facts from previous run OK
debug:
var: ansible_date_time.epoch
- name: Sleep for 4s
command: sleep 4

- hosts: localhost
connection: local
tasks:
- name: Facts from previous run NOT OK
debug:
var: ansible_date_time.epoch

Command:

ansible-playbook -i localhost, ./demo.yml

EXPECTED RESULTS

Either maintain consistency with other fact caching mechanisms and the fact should never change during the run.

OR

A more-correct solution I feel is the third Play should refresh expired facts.

ACTUAL RESULTS

$ ansible-playbook -i localhost, ./demo.yml

PLAY [localhost] *******************************************************************************************************

TASK [Gathering Facts] *************************************************************************************************
ok: [localhost]

TASK [Facts gathereed OK] **********************************************************************************************
ok: [localhost] => {
"ansible_date_time.epoch": "1504289061",
"changed": false
}

TASK [Sleep for a few seconds] *****************************************************************************************
changed: [localhost]

PLAY [localhost] *******************************************************************************************************

TASK [Facts from previous run OK] **************************************************************************************
ok: [localhost] => {
"ansible_date_time.epoch": "1504289061",
"changed": false
}

TASK [Sleep for 4s] ****************************************************************************************************
changed: [localhost]

PLAY [localhost] *******************************************************************************************************

TASK [Facts from previous run NOT OK] **********************************************************************************
ok: [localhost] => {
"ansible_date_time.epoch": "VARIABLE IS NOT DEFINED!",
"changed": false
}

PLAY RECAP *************************************************************************************************************
localhost : ok=6 changed=2 unreachable=0 failed=0