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

local_action's working directory is based on the topmost playbook, so is unpredictable from included files #5344

Closed
josephtate opened this issue Dec 19, 2013 · 12 comments

Comments

@josephtate
Copy link
Contributor

From experimentation it appears that when you

- name: Get local dir
  local_action: shell pwd
  register: result
- name: Debug result
  debug: var=result

That the cwd for the script run by the local_action is set to the directory where the top-most playbook is located. This is the case whether you launch from the same directory as the playbook or a different directory.

So if you have a playbook like

#file site.yml
- hosts:
    - webservers
  roles:
    - common

And then a roles/common/tasks/main.yml contains:

- name: Check to see if there is an ssl key
  local_action: shell [ -f ./<some relative path>/{{hostname}}.key ]
  register: key_file
  failed_when: key_file.rc > 1

The role file has to specify a path relative to "site.yml" not to itself in order for the local_action to find the file. So, instead of using ../files/{{hostname}}.key, I have to know where the original playbook is and use a path that starts there, like "roles/common/files/{{hostname}}.key". The stat module is the same way, so it's not just "shell".

It appears that an include from a role file does not change the local_action cwd either.

I'm actually not exactly sure what I want to happen, but since other yaml sections (like the copy and template modules and the include directive) use some sort of local context to figure out where to find files, I'd like to be able to use a similar system for running context aware scripts on the local system. I suppose I could replace the "test -f" for a find command, but what if the file needs to be looked up in a non-child directory?

@mpdehaan
Copy link
Contributor

So yes, this is true. However, local action is not really different from remotes in that you need to specify chdir and it shouldn't be scribbling around in the static playbook dir.

I think I'm ok with this behavior. This is probably better served as a discussion on ansible-devel so we can understand further what the implications might be among a larger audience.

Can you start a thread? Thanks!

@rdolejsi
Copy link

I've come across the same limitation practically denying me to use roles effectively. I have found a practical "workaround" / solution. As per the suggestion below -

The approach I'm currently using to solve this is to define a variable {{ current_role }} at the beginning of each role containing the current role name.

This in turn allows me to always get files from roles/{{ current_role }}/files/my_desired_file.

This works fine until Ansible 1.7.1. It is broken in the current devel, though - defining {{ current_role }} using load_vars: accidentally loads the last current_role in the chain, thus rendering the whole approach unusable. Using set_fact might make it work again, albeit not so elegantly..

@rdolejsi
Copy link

Just a clarification - what I've described is useful when re-using the same YML file from different roles, yet having different files/ content for each role.

In case you want to load always the same file, you are better off with specifying the exact path the file resides in.

@srgvg
Copy link
Contributor

srgvg commented Sep 17, 2014

FYI, in 1.8 there is a new special variable 'role_path'

On 17 September 2014 18:02, rdolejsi notifications@github.com wrote:

I've come across the same limitation practically denying me to use roles
effectively. I have found a practical "workaround" / solution. As per the
suggestion below -

The approach I'm currently using to solve this is to define a variable {{
current_role }} at the beginning of each role containing the current role
name.

This in turn allows me to always get files from roles/{{ current_role
}}/files/my_desired_file.

This works fine until Ansible 1.7.1. It is broken in the current devel,
though - defining {{ current_role }} using load_vars: accidentally loads
the last current_role in the chain, thus rendering the whole approach
unusable. Using set_fact might make it work again, albeit not so elegantly..


Reply to this email directly or view it on GitHub
#5344 (comment).

@rdolejsi
Copy link

Hmm, that fits my current needs nicely :-)

I guess to support both scenarios (i.e. get the local files off YML location within specific role) we would also need to introduce something like 'current_file_path' or 'current_file_role_path' - allowing to base the supplementary files for given task off the role the task is within rather than current role.

@srgvg
Copy link
Contributor

srgvg commented Sep 17, 2014

On 17 September 2014 20:31, rdolejsi notifications@github.com wrote:

something like 'current_file_path' or 'current_file_role_path'

​not sure what you mean here, but the role_path I mentioned is the full
absolute path of the role, so you just need to append e.g. /files/​

@rdolejsi
Copy link

Just to make sure - is role_path:

  • current role I'm running at the moment
  • the role in which the YML file is

.. I'm reusing YML files and tasks within from other roles, kinda like a library. Some of such reused tasks need to access files located within their respective roles, some need to access files within my current role. These are actually two different scenarios...

@rdolejsi
Copy link

  • The first scenario (current role) is usable when the "library" task expects files/ in my current role
  • The second scenario (role of the file with the task I'm calling) helps to write relocatable tasks across roles

@srgvg
Copy link
Contributor

srgvg commented Sep 17, 2014

Just to make sure - is role_path:

  • current role I'm running at the moment

​more precisely the full absolute path to the current role that is running​

  • the role in which the YML file is

​No, if you directly include a task yml file​

​from a role elsewhere, this won't work.

@rdolejsi
Copy link

No issues, I will evaluate it Tomorrow to see how useful it is for my scenario - thanks a lot for the info..

@tetherit
Copy link

tetherit commented Mar 4, 2015

Thank you path: '{{ role_path }}/files/{{ item }}' is what I was looking for!

@sruslanas
Copy link

@xanview thank you, that approach is working fine.

@ansible ansible locked and limited conversation to collaborators Apr 24, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants