在当前Ansible角色的文件部分中查找文件名

时间:2014-06-16 19:03:32

标签: ansible ansible-playbook

我对Ansible相当新,我试图创建一个将文件复制到远程服务器的角色。每次我运行playbook时,本地文件都可以有不同的名称,但需要远程复制到同一名称,如下所示:

- name: copy file
  copy:
    src=*.txt
    dest=/path/to/fixedname.txt

Ansible不允许使用通配符,所以当我用主要剧本中的任务编写一个简单的剧本时,我可以这样做:

- name: find the filename
    connection: local
    shell: "ls -1 files/*.txt"
    register: myfile

- name: copy file
  copy:
    src="files/{{ item }}"
    dest=/path/to/fixedname.txt
  with_items:
   - myfile.stdout_lines

然而,当我将任务移动到某个角色时,第一个动作不再起作用,因为相对路径是相对于角色的,而剧本在角色的根目录中执行&# 39;目录。我可以添加角色文件目录的路径,但是有更优雅的方式吗?

2 个答案:

答案 0 :(得分:13)

看起来您需要访问在本地查找信息的任务,然后将该信息用作复制模块的输入。

获取本地信息有两种方法。

  • 使用local_action:。再次运行任务的简写为127.0.0.1,找到了更多信息here。 (这是你一直在使用的)

  • 使用lookup。这是一个专门用于在本地获取信息的插件系统。更多信息here

在你的情况下,我会使用lookup来寻找第二种方法。您可以将其设置为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    

或者,更直接地说:

tasks:
  - name: copy file
    copy: src="{{ lookup('pipe', 'ls -1 files/*.txt') }}" dest=/path/to/fixedname.txt    

关于路径

查找插件从任务的上下文(playbook vs role)运行。这意味着它的行为会有所不同,具体取决于它的使用位置。

在上面的设置中,任务直接从剧本中运行,因此工作目录将是:

/path/to/project - 这是您的剧本所在的文件夹。

如果您将任务添加到角色,则工作目录将为:

/path/to/project/roles/role_name/tasks

此外,filepipe插件在角色/文件文件夹中运行

/path/to/project/roles/role_name/files - 这表示您的命令为ls -1 *.txt

警告:

每次访问变量时都会调用该插件。这意味着你不能相信你在剧本中调试变量,然后在角色稍后使用时依赖变量来获得相同的值!

我确实想知道关于项目ansible文件夹中的文件的用例,但事先并不知道谁的名字。这样的文件来自哪里?是不是可以在文件的生成和在Ansible中使用它或在固定的本地路径作为变量之间添加一个层?只是好奇;)

答案 1 :(得分:8)

只是想提出一个额外的答案......我遇到了和你一样的问题,我在飞行中构建一个ansible软件包并将工件(rpms)复制到一个角色的文件夹中,我的rpms中有版本文件名。

当我运行ansible游戏时,我希望它安装所有的rpms,无论文件名如何。

我在ansible中使用with_fileglob机制解决了这个问题:

- name: Copy RPMs
  copy: src="{{ item }}" dest="{{ rpm_cache }}"
  with_fileglob: "*.rpm"
  register: rpm_files

- name: Install RPMs
  yum: name={{ item }} state=present
  with_items: "{{ rpm_files.results | map(attribute='dest') | list }}"

我发现它比查找机制更清晰。