Ansible:如何将文件从`files`目录复制到角色目录中的`templates`目录?

huangapple go评论85阅读模式
英文:

Ansible: How to copy file from `files` directory to `templates` directory in a role directory?

问题

我想编写一个Ansible任务,将文件从files目录复制到templates目录。

例如,我有一个名为data的Ansible角色,并且在此角色的目录内部:

~/data$ tree
.
├── defaults
├── tasks
├── templates
└── files
    └── application.j2

因此,我在files目录中有一个名为application.j2的文件。

我想使用Ansible任务将此文件application.j2复制到templates目录中。

我尝试在下面的任务中使用以下路径src:中的路径files/application.j2,但我不知道应该在dest:路径中写什么。

- name: Transfer File.
  copy:
    src: "{{ item }}"
    dest: 
  with_fileglob:
    - "files/application.j2"

Ansible:如何在角色目录中将文件从files目录复制到templates目录?

英文:

I want to write an Ansible task to copy file from files directory to templates directory.

For example, I have an Ansible role named data and inside this role's directory

~/data$ tree
.
├── defaults
├── tasks
├── templates
└── files
    └── application.j2

So I have a file inside the files directory named application.j2

I want to copy this file application.j2 into the templates directory using an Ansible task.

I've tried to use the below task in the src: path I use files/application.j2 but I don't know what I should write in dest: path.

- name: Transfer File.
   copy:
    src: "{{ item }}"
    dest: 
  with_fileglob:
    - "files/application.j2"

Ansible: How to copy file from files directory to templates directory in a role directory?

答案1

得分: 1

Q: "将文件从'files'目录复制到'role'目录中的'templates'目录。"

A: 我将这个问题理解为: "什么是角色的目录?"

如果你正在一个角色中运行任务,你可以使用特殊变量role_path。但这里不是这种情况。你想要在playbook中的任务中从角色内部复制文件。声明一个包含角色和要在'directories'之间传输的文件的字典

  transfer_files:
    data:
      - application.j2

可能会在DEFAULT_ROLES_PATH中有更多的目录。例如,

shell> grep roles_path ansible.cfg 
roles_path = $PWD/roles:$PWD/roles2:$PWD/roles3

获取变量

  my_roles_path: "{{ lookup('config', 'DEFAULT_ROLES_PATH') }}"

会得到

  my_roles_path:
  - /scratch/tmp7/test-359/roles
  - /scratch/tmp7/test-359/roles2
  - /scratch/tmp7/test-359/roles3

查找所有角色

    - find:
        paths: "{{ my_roles_path }}"
        file_type: directory
        depth: 1
      register: my_roles_out

并声明变量

  my_roles: "{{ my_roles_out.files|map(attribute='path') }}"
  my_roles_dict: "{{ dict(my_roles|map('basename')|
                          zip(my_roles|map('dirname'))) }}"

会得到

  my_roles:
  - /scratch/tmp7/test-359/roles/data
  - /scratch/tmp7/test-359/roles2/roleX
  - /scratch/tmp7/test-359/roles3/roleY

  my_roles_dict:
    data: /scratch/tmp7/test-359/roles
    roleX: /scratch/tmp7/test-359/roles2
    roleY: /scratch/tmp7/test-359/roles3

现在,你可以复制文件

    - copy:
        src: "{{ role_path }}/files/{{ item.1 }}"
        dest: "{{ role_path }}/templates/{{ item.1 }}"
      loop: "{{ transfer_files|dict2items|subelements('value') }}"
      vars:
        role_path: "{{ my_roles_dict[item.0.key] }}/{{ item.0.key }}"

得到

shell> tree .
.
├── ansible.cfg
├── hosts
├── pb.yml
├── roles
│   └── data
│       ├── defaults
│       ├── files
│       │   └── application.j2
│       ├── tasks
│       └── templates
│           └── application.j2   <-- from files
├── roles2
│   └── roleX
└── roles3
    └── roleY

完整的测试playbook示例

- hosts: localhost

  vars:

    my_roles_path: "{{ lookup('config', 'DEFAULT_ROLES_PATH') }}"
    my_roles: "{{ my_roles_out.files|map(attribute='path') }}"
    my_roles_dict: "{{ dict(my_roles|map('basename')|
                            zip(my_roles|map('dirname'))) }}"

    transfer_files:
      data:
        - application.j2

  tasks:

    - debug:
        var: my_roles_path

    - find:
        paths: "{{ my_roles_path }}"
        file_type: directory
        depth: 1
      register: my_roles_out

    - debug:
        var: my_roles
    - debug:
        var: my_roles_dict

    - copy:
        src: "{{ role_path }}/files/{{ item.1 }}"
        dest: "{{ role_path }}/templates/{{ item.1 }}"
      loop: "{{ transfer_files|dict2items|subelements('value') }}"
      vars:
        role_path: "{{ my_roles_dict[item.0.key] }}/{{ item.0.key }}"

英文:

Q: "Copy files from files directory to templates directory in a role."

Given the project for testing

shell> pwd
/scratch/tmp7/test-359
shell> tree .
.
├── ansible.cfg
├── hosts
├── pb.yml
├── roles
│   └── data
│       ├── defaults
│       ├── files
│       │   └── application.j2
│       ├── tasks
│       └── templates
├── roles2
│   └── roleX
└── roles3
    └── roleY

A: I read this question as: "What is the directory of a role?"

If you're running a task in a role you can use the special variable role_path. But, this is not the case here. You want to copy the files inside the roles from a task in a playbook. Declare a dictionary with the roles and files you want to transfer between the directories files and templates

  transfer_files:
    data:
      - application.j2

There might be more directories in DEFAULT_ROLES_PATH. For example,

shell> grep roles_path ansible.cfg 
roles_path = $PWD/roles:$PWD/roles2:$PWD/roles3

Get the variable

  my_roles_path: "{{ lookup('config', 'DEFAULT_ROLES_PATH') }}"

gives

  my_roles_path:
  - /scratch/tmp7/test-359/roles
  - /scratch/tmp7/test-359/roles2
  - /scratch/tmp7/test-359/roles3

Find all roles

    - find:
        paths: "{{ my_roles_path }}"
        file_type: directory
        depth: 1
      register: my_roles_out

and declare the variables

  my_roles: "{{ my_roles_out.files|map(attribute='path') }}"
  my_roles_dict: "{{ dict(my_roles|map('basename')|
                          zip(my_roles|map('dirname'))) }}"

gives

  my_roles:
  - /scratch/tmp7/test-359/roles/data
  - /scratch/tmp7/test-359/roles2/roleX
  - /scratch/tmp7/test-359/roles3/roleY

  my_roles_dict:
    data: /scratch/tmp7/test-359/roles
    roleX: /scratch/tmp7/test-359/roles2
    roleY: /scratch/tmp7/test-359/roles3

Now, you can copy the file(s)

    - copy:
        src: "{{ role_path }}/files/{{ item.1 }}"
        dest: "{{ role_path }}/templates/{{ item.1 }}"
      loop: "{{ transfer_files|dict2items|subelements('value') }}"
      vars:
        role_path: "{{ my_roles_dict[item.0.key] }}/{{ item.0.key }}"

gives

shell> tree .
.
├── ansible.cfg
├── hosts
├── pb.yml
├── roles
│   └── data
│       ├── defaults
│       ├── files
│       │   └── application.j2
│       ├── tasks
│       └── templates
│           └── application.j2   <-- from files
├── roles2
│   └── roleX
└── roles3
    └── roleY

<hr>

<sup>

Example of a complete playbook for testing

- hosts: localhost

  vars:

    my_roles_path: &quot;{{ lookup(&#39;config&#39;, &#39;DEFAULT_ROLES_PATH&#39;) }}&quot;
    my_roles: &quot;{{ my_roles_out.files|map(attribute=&#39;path&#39;) }}&quot;
    my_roles_dict: &quot;{{ dict(my_roles|map(&#39;basename&#39;)|
                            zip(my_roles|map(&#39;dirname&#39;))) }}&quot;

    transfer_files:
      data:
        - application.j2

  tasks:

    - debug:
        var: my_roles_path

    - find:
        paths: &quot;{{ my_roles_path }}&quot;
        file_type: directory
        depth: 1
      register: my_roles_out

    - debug:
        var: my_roles
    - debug:
        var: my_roles_dict

    - copy:
        src: &quot;{{ role_path }}/files/{{ item.1 }}&quot;
        dest: &quot;{{ role_path }}/templates/{{ item.1 }}&quot;
      loop: &quot;{{ transfer_files|dict2items|subelements(&#39;value&#39;) }}&quot;
      vars:
        role_path: &quot;{{ my_roles_dict[item.0.key] }}/{{ item.0.key }}&quot;

</sup>

答案2

得分: 0

让我们假设有人想要:

  • 在不同文件夹之间复制带有模式的文件
  • 让任务仅在 Ansible 控制节点上运行

一个最小示例的Playbook

---
- hosts: localhost
  become: false
  gather_facts: false

  tasks:

  - name: 复制与给定模式匹配的每个文件
    copy:
      src: "{{ item }}"
      dest: "templates/{{ item.split('.') | first | basename }}.j2"
    with_fileglob:
      - "files/app*.j2"

将产生所请求的输出。

类似的问答

有关更详细的解释,请参阅答案:

英文:

Let's assume one like to

  • Copy files with patterns between different folders
  • Let the task run on the Ansible Control Node only

A minimal example playbook

---
- hosts: localhost 
  become: false
  gather_facts: false

  tasks:

  - name: Copy each file that matches the given pattern
    copy:
      src: &quot;{{ item }}&quot;
      dest: &quot;templates/{{ item.split(&#39;.&#39;) | first | basename }}.j2&quot;
    with_fileglob:
      - &quot;files/app*.j2&quot;

will result into the requested output.

Similar Q&A

For a more detailed explanation see the answer under

huangapple
  • 本文由 发表于 2023年5月26日 14:51:43
  • 转载请务必保留本文链接:https://go.coder-hub.com/76338291.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定