Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

backup files in host_vars override vars.yml #17382

Closed
rodmanning opened this issue Sep 4, 2016 · 4 comments · Fixed by #23415
Closed

backup files in host_vars override vars.yml #17382

rodmanning opened this issue Sep 4, 2016 · 4 comments · Fixed by #23415
Labels
affects_1.9 This issue/PR affects Ansible v1.9 affects_2.0 This issue/PR affects Ansible v2.0 affects_2.1 This issue/PR affects Ansible v2.1 affects_2.2 This issue/PR affects Ansible v2.2 bug This issue/PR relates to a bug. c:vars/hostvars

Comments

@rodmanning
Copy link

ISSUE TYPE
  • Bug Report
COMPONENT NAME

host_vars configuration

ANSIBLE VERSION
ansible 2.1.1.0
  config file = /home/rod/deltoid/servers/ansible/ansible.cfg
  configured module search path = Default w/o overrides
CONFIGURATION

Added vault password file path to ansible.cfg, nothing else.

OS / ENVIRONMENT

Arch linux (x86_64)

SUMMARY

When reading host_vars, ansible reads vars from a file name "vars.yml~" with priority over a file name "vars.yml". The "vars.yml~" file was created by editing the original file with emacs, which saves the backup by appending a "~" to the filename.

STEPS TO REPRODUCE

Create host_vars in a folder as follows:

ansible-folder
- host_vars
  - my-server-01
    - vars.yml
        ansible_user: root
        ansible_port: 22
    - vars.yml~
        ansible_user: someone_else
        ansible_port: 9999

When connecting to a host (e.g. ansible -i hosts all -m ping), ansible will use the vars saved in vars.yml~.

EXPECTED RESULTS

Expected to connect with 'root' on port 22, etc.

Using /home/rod/deltoid/servers/ansible/ansible.cfg as config file
SSH password: 
Loaded callback minimal of type stdout, v2.0
<dlt-tx-02> ESTABLISH SSH CONNECTION FOR USER: root
<dlt-tx-02> SSH: EXEC sshpass -d13 ssh -C -vvv -o ControlMaster=no -o ControlPersist=no -o Port=22 -o User=root -o ConnectTimeout=10 -o ControlPath=/dev/null dlt-tx-02 '/bin/sh -c '"'"'( umask 77 && mkdir -p "` echo $HOME/.ansible/tmp/ansible-tmp-1472954078.5-25255107732476 `" && echo ansible-tmp-1472954078.5-25255107732476="` echo $HOME/.ansible/tmp/ansible-tmp-1472954078.5-25255107732476 `" ) && sleep 0'"'"''
<dlt-tx-02> PUT /tmp/tmpldCjDh TO /root/.ansible/tmp/ansible-tmp-1472954078.5-25255107732476/ping
<dlt-tx-02> SSH: EXEC sshpass -d13 sftp -o BatchMode=no -b - -C -vvv -o ControlMaster=no -o ControlPersist=no -o Port=22 -o User=root -o ConnectTimeout=10 -o ControlPath=/dev/null '[dlt-tx-02]'
<dlt-tx-02> ESTABLISH SSH CONNECTION FOR USER: root
<dlt-tx-02> SSH: EXEC sshpass -d13 ssh -C -vvv -o ControlMaster=no -o ControlPersist=no -o Port=22 -o User=root -o ConnectTimeout=10 -o ControlPath=/dev/null -tt dlt-tx-02 '/bin/sh -c '"'"'LANG=en_AU.UTF-8 LC_ALL=en_AU.UTF-8 LC_MESSAGES=en_AU.UTF-8 /usr/bin/python /root/.ansible/tmp/ansible-tmp-1472954078.5-25255107732476/ping; rm -rf "/root/.ansible/tmp/ansible-tmp-1472954078.5-25255107732476/" > /dev/null 2>&1 && sleep 0'"'"''
dlt-tx-02 | SUCCESS => {
    "changed": false, 
    "invocation": {
        "module_args": {
            "data": null
        }, 
        "module_name": "ping"
    }, 
    "ping": "pong"
}
ACTUAL RESULTS

Ansible generated an ssh command for the incorrect user/port.

Using /home/rod/deltoid/servers/ansible/ansible.cfg as config file
SSH password: 
Loaded callback minimal of type stdout, v2.0
<dlt-tx-02> ESTABLISH SSH CONNECTION FOR USER: someone_else
<dlt-tx-02> SSH: EXEC sshpass -d13 ssh -C -vvv -o ControlMaster=no -o ControlPersist=no -o Port=9999 -o User=someone_else -o ConnectTimeout=10 -o ControlPath=/dev/null dlt-tx-02 '/bin/sh -c '"'"'( umask 77 && mkdir -p "` echo $HOME/.ansible/tmp/ansible-tmp-1472954135.94-221184064468334 `" && echo ansible-tmp-1472954135.94-221184064468334="` echo $HOME/.ansible/tmp/ansible-tmp-1472954135.94-221184064468334 `" ) && sleep 0'"'"''
dlt-tx-02 | UNREACHABLE! => {
    "changed": false, 
    "msg": "Failed to connect to the host via ssh.", 
    "unreachable": true
}
@ansibot ansibot added triage affects_2.1 This issue/PR affects Ansible v2.1 labels Sep 7, 2016
@bcoca bcoca added affects_2.0 This issue/PR affects Ansible v2.0 affects_1.9 This issue/PR affects Ansible v1.9 affects_2.2 This issue/PR affects Ansible v2.2 and removed triage labels Sep 9, 2016
@georgebuckerfield
Copy link

I've been able to replicate this. I think it's due to the behaviour of the _load_inventory_file() function in lib/ansible/vars/__init__.py.
The list of files to be loaded is sorted using sort(), which leaves a filename appended with a ~ character to be loaded later:
[u'localhost.yml', u'localhost.yml~']

You can avoid those files being loaded with an extra condition on the for loop that follows, but I don't know if that's desirable behaviour.
e.g.

# do not parse hidden files or dirs, e.g. .svn/
paths = [os.path.join(path, name) for name in names if not name.startswith('.') and not name.endswith('~')]

@ceving
Copy link

ceving commented Jan 31, 2017

Same bug here with group_vars.

@rodmanning
Copy link
Author

Thanks @george-buckerfield, that's exactly the behaviour I'd be wanting. I've looked at that part of the code and agree with your take on it.

My take on desirable behaviour: saving with a "~" extension for backup files is the default behaviour for both vim & emacs, so makes sense to exclude these when parsing hostvars and groupvars.

Alternatively might be to reverse the sort order, so that backup files were parsed first and over-written by variables in the actual file. (Personally think that's less transparent than just not parsing it at all though.)

Does anyone want a pull request for this, or is more discussion needed about whether or not this is desireable behaviour?

@georgebuckerfield
Copy link

@rodmanning I had a PR ready to go a while back, so I've submitted it. Happy to modify it based on any feedback though.

bcoca added a commit to bcoca/ansible that referenced this issue Apr 13, 2017
fixes ansible#17382
alternate to ansible#22979

deal with cases in which group/host have . in name
updated as per feedbck
only be strict about extension when doing dirs
also avoid ~ endings
bcoca added a commit that referenced this issue Apr 20, 2017
fixes #17382
alternate to #22979

deal with cases in which group/host have . in name
updated as per feedbck
only be strict about extension when doing dirs
also avoid ~ endings
bcoca added a commit that referenced this issue Apr 20, 2017
fixes #17382
alternate to #22979

deal with cases in which group/host have . in name
updated as per feedbck
only be strict about extension when doing dirs
also avoid ~ endings

(cherry picked from commit 602a2bc)
@ansibot ansibot added bug This issue/PR relates to a bug. and removed bug_report labels Mar 7, 2018
@ansible ansible locked and limited conversation to collaborators Apr 25, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
affects_1.9 This issue/PR affects Ansible v1.9 affects_2.0 This issue/PR affects Ansible v2.0 affects_2.1 This issue/PR affects Ansible v2.1 affects_2.2 This issue/PR affects Ansible v2.2 bug This issue/PR relates to a bug. c:vars/hostvars
Projects
None yet
5 participants