cannot use lookup on paths with a space
muelli opened this issue · 2 comments
I am trying to use the MySQL role and debops uses the lookup function to locate a password.
That, however, does not work when the directory contains spaces.
TASK: [debops.mysql | debug var=secret] ***************************************
ok: [default] => {
"var": {
"secret": "/home/muelli/vcs/repository/2015 Projects Deliverables/some more spaces/ansible/../secret"
}
}
TASK: [debops.mysql | Manage MySQL users] *************************************
fatal: [default] => Failed to template {{ item.password | default(lookup("password", secret|replace(" ", "\\ ") + "/credentials/" + ansible_fqdn + "/mysql/" + item.name + "/password length=" + mysql_password_length)) }}: need more than 1 value to unpack
FATAL: all hosts have already failed -- aborting
The playbook is as simple as that:
- hosts: all
sudo: yes
vars:
# Hm, mysql seems to be locked
tcpwrappers: False
pre_tasks:
### This is more logic for detecting whether mysql is already installed
- name: Check if foo is installed
command: dpkg-query -l mysql-server
failed_when: False
changed_when: False
register: deb_check
- debug: var=ohai_ip_address
- command: echo Always restart mysql prior to making changes...
# Because when we already run with --skip-grant-tables then we
# cannot update users' passwords.
changed_when: True
# This does not necessarily help when mysqld is not yet installed :(
failed_when: False
# So we add more logic here
when: deb_check.stdout.find('no packages found') != -1
notify: ['Restart mysql']
roles:
# Include SSHd so that SSH access (for ansible) will be allowed
- debops.sshd
- role: debops.mysql
mysql_mysqld_bind_address: '0.0.0.0'
mysql_root_password: root
mysql_users:
- name: root
host: '%'
password: 'root'
priv: mysql.*:ALL
append_privs: yes
state: present
and I run ansible like this:
env ANSIBLE_FILTER_PLUGINS=~/.ansible/plugins/filter_plugins/:/usr/share/ansible_plugins/filter_plugins:~/vcs/debops.playbooks/playbooks/filter_plugins/ ANSIBLE_LOOKUP_PLUGINS=~/.ansible/plugins/lookup_plugins/:/usr/share/ansible:~/vcs/debops.playbooks/playbooks/:~/vcs/debops.playbooks/playbooks/library/database/ldap/:~/vcs/debops.playbooks/playbooks/library/database/:~/vcs/debops.playbooks/playbooks/library/database/ ANSIBLE_ROLES_PATH=~/vcs/:~/vcs/ansible-hydra/roles ANSIBLE_LIBRARY=~/vcs/debops.playbooks/playbooks/library/ ANSIBLE_FORCE_COLOR=true ANSIBLE_HOST_KEY_CHECKING=false PYTHONUNBUFFERED=1 ANSIBLE_SSH_ARGS='-o ForwardAgent=yes -o ControlMaster=auto -o ControlPersist=60s' ansible-playbook --private-key=/home/muelli/.vagrant.d/insecure_private_key --user=vagrant --connection=ssh --inventory-file=ansible/vagrant_ansible_inventory -vv --limit='all' ansible/playbook.yml
I expected it to work fine, because it does in a directory without spaces.
It looks like the Ansible password
lookup plugin does not handle paths with spaces correctly. You can test this using the playbook:
---
- hosts: localhost
vars:
dir: '/tmp/dir with spaces'
tasks:
- name: Lookup the password
set_fact:
pass: '{{ lookup("password", dir + "/subdir/password") }}'
- name: Display password
debug: var=pass
When the file is created manually and looked up with file
plugin, Ansible works correctly.
I suggest that you should create an issue in the Ansible project repository about this. It cannot be sloved with a playbook change.
yep, that fails:
>cat ansible/playbook.yml
---
- hosts: localhost
vars:
dir: '/tmp/dir with spaces'
tasks:
- name: Lookup the password
set_fact:
pass: '{{ lookup("password", dir + "/subdir/password") }}'
- name: Display password
debug: var=pass
>
ansible-playbook --inventory-file=ansible/vagrant_ansible_inventory -vv ansible/playbook.yml
[WARNING]: provided hosts list is empty, only localhost is available
PLAY [localhost] **************************************************************
GATHERING FACTS ***************************************************************
<localhost> REMOTE_MODULE setup
ok: [localhost]
TASK: [Lookup the password] ***************************************************
fatal: [localhost] => Failed to template {{ lookup("password", dir + "/subdir/password") }}: need more than 1 value to unpack
FATAL: all hosts have already failed -- aborting
PLAY RECAP ********************************************************************
to retry, use: --limit @/home/muelli/playbook.retry
localhost : ok=1 changed=0 unreachable=1 failed=0
Other lookup plugins work (well, I've only tested the file one), but the password one seems to be broken.
Let me file a bug.