It looks like you need access to a task that looks up information locally, and then uses that information as input to the copy module.
There are two ways to get local information.
use local_action:
. That's shorthand for running the task agains 127.0.0.1, more info found here. (this is what you've been using)
use a lookup
. This is a plugin system specifically designed for getting information locally. More info here.
In your case, I would go for the second method, using lookup
. You could set it up like this example:
vars:
local_file_name: "{{ lookup('pipe', 'ls -1 files/*.txt') }}"
tasks:
- name: copy file
copy: src="{{ local_file_name }}" dest=/path/to/fixedname.txt
Or, more directly:
tasks:
- name: copy file
copy: src="{{ lookup('pipe', 'ls -1 files/*.txt') }}" dest=/path/to/fixedname.txt
With regards to paths
the lookup plugin is run from the context of the task (playbook vs role). This means that it will behave differently depending on where it's used.
In the setup above, the tasks are run directly from a playbook, so the working dir will be:
/path/to/project
-- this is the folder where your playbook is.
If you where to add the task to a role, the working dir would be:
/path/to/project/roles/role_name/tasks
In addition, the file
and pipe
plugins run from within the role/files folder if it exists:
/path/to/project/roles/role_name/files
-- this means your command is ls -1 *.txt
caveat:
The plugin is called every time you access the variable. This means you cannot trust debugging the variable in your playbook, and then relying on the variable to have the same value when used later in a role!
I do wonder though, about the use-case for a file that resides inside a projects ansible folders, but who's name is not known in advance. Where does such a file come from? Isn't it possible to add a layer in between the generation of the file and using it in Ansible... or having a fixed local path as a variable? Just curious ;)
Handlers are just tasks that Ansible will run at the end of a play if necessary. Given that they're implicitly added to the end of your play, they're going to be treated the same as any other tasks as far as parameters like serial
go. Unfortunately this means that without a feature request that the Ansible developers accept you're unlikely to see a change in the behavior of serial
to support what you're trying to do.
I know you mentioned wanting to avoid hacks, but that's going to be the only way you can do something like this at this point. It shouldn't be too difficult to set up something that's not a major hack, like creating a temporary file to flag the restart:
- hosts: some_hosts
name: install service
serial: 10
- handlers:
- name: schedule restart
command: touch /tmp/restart_flag
- tasks:
- name: install service
action: whatever...
notify: schedule restart
- hosts: some_hosts
name: restart service
serial: 2
- handlers:
- name: perform restart
service: name=foo state=restarted
- tasks:
- name: Delete /tmp/restart_flag. Restart service if file is deleted.
file: path=/tmp/restart_flag state=absent
notify: perform restart
Best Answer
You can also call handlers of a dependency role. May be cleaner than including files or explicitly listing roles in a playbook just for the purpose of role to role relationship. E.g.:
roles/my-handlers/handlers/main.yml
roles/my-other/meta/main.yml
roles/my-other/tasks/main.yml