Ansible - 使用注册的变量值查找

利乔亚伯拉罕

我想在这里实现的目标如下

  1. 从 tar.gz 解压缩代码 - 工作
  2. 在未归档的目录中查找文件名 - 工作
  3. 根据在步骤 2 中获取的文件名在代码目录中查找文件名 -失败
  4. 从源复制文件:(第 2 步)目标:(第 3 步) - 如果我在第 3 步的模式部分使用硬编码文件名,则工作

下面提到的是我使用过的 Ansible 角色:

- name: Unarchive config files to server
  unarchive:
    src: "{{ config_dir }}/config.tar.gz"
    dest: /tmp
    list_files: yes
  register: tar_path

- name: Find file names in unarchived config files
  find:
    paths: "{{ tar_path.dest }}"
    file_type: file
    recurse: yes
  register: tmp_file_path

- name: Find file names in code base
  find:
    paths: /opt
    file_type: file
    recurse: yes
    patterns:
      #Search for file names with the values in tmp_file_path
  register: code_file_path

- set_fact:
    code_files: "{{ code_files|default([]) +
                    [{'path': item, 'name': item|basename}] }}"
  loop: "{{ code_file_path.files|map(attribute='path')|list }}"

- name: copy files
  command: cp "{{ item.0 }}" "{{ item.1.path }}"
  with_together:
    - "{{ tmp_file_path.files|map(attribute='path')|list|sort }}"
    - "{{ code_files|sort(attribute='name') }}"

在这里,我需要使用 find 根据模式(文件名)在 /opt 目录中定位文件,正是我在 /tmp 中未归档的

最后,根据文件名和路径将文件从 /tmp 替换为 /opt(我可以这样做)。目录结构如下:

shell> tree tmp
tmp
├── file1
├── file2
└── file3

shell> tree opt
opt
├── bar
│   └── file2
├── baz
│   └── file3
└── foo
    └── file1

在这里,如果我使用下面的代码,其中我手动提到了文件名,那么它就可以工作。但是,我不想这样做

- name: Find file names in code base
  find:
    paths: /opt
    file_type: file
    recurse: yes
    patterns:
      - file1
      - file2
      - file3
  register: code_file_path

我需要一个解决方案来替换模式的硬编码:file1、file2 和 file3,并使用一些变量来做到这一点。我需要替换的 /tmp 和 /opt 中的文件名完全相同

Zeitounator

如果我理解正确,这里有一种可能的方法来处理您正在尝试做的事情。在下面的示例中,我取消了未归档的作业,因为它不在关键路径上。

剧本演练

  • 我创建了两个示例目录。前两个任务只是为了进一步向您展示这个测试结构:

    1. 一个archive包含随机目录4个文件的目录。其中之一不在目标中
    2. 一个code包含多个文件随机目录的目录。3 个文件与archive.
  • 第一个find任务与您的任务相同,并使用archive目录中所有文件的详细信息注册结果

  • 对于目录中的第二个find任务code,关键点是patterns将第一次搜索中的基本名称列表作为参数传递,您可以使用表达式获取该列表:

    {{ search_archive.files | map(attribute='path') | map('basename') | list }}
    

    我们可以将其详细描述为:files从我们的存档find结果中获取列表,仅提取path属性,对每个列表元素应用basename过滤器并返回一个列表。

  • 对于最后一个任务,我使用了copy模块. 我的示例在 localhost 上运行,但由于您的示例可能会在远程目标上运行,因此remote_src必须设置它(或者将从控制器获取文件)。

    循环是在上一个任务的结果上完成的,所以我们只得到代码目录中的匹配文件为dest. 为了选择src,我们使用以下表达式在存档文件夹中查找相应的文件:

    {{ search_archive.files | map(attribute='path') | select('match', '^.*/' + item | basename + '$') | first }}
    

    选择过滤器selectmatch测试应用于列表中的每个路径,仅选择以当前代码路径基名结尾的元素。first过滤器只得到第一个(只在您的案件)匹配的元素。loop_control.label用于获得更好的任务结果输出。

演示剧本

前两个任务仅用于调试/演示目的。

---
- name: Update files from package in code wherever they are
  hosts: localhost
  gather_facts: false

  tasks:

    - name: Capture sample data structure
      command: tree archive code
      register: structure
      changed_when: false

    - name: Show sample data structure
      debug:
        msg: "{{ structure.stdout_lines}}"

    - name: Find files in archive
      find:
        paths: archive
        file_type: file
        recurse: yes
      register: search_archive

    - name: Find files in code matching names in archive
      find:
        paths: code
        file_type: file
        recurse: yes
        patterns:  >-
          {{
            search_archive.files |
            map(attribute='path') |
            map('basename') |
            list
          }}
      register: search_code

    - name: Copy files from archive to code
      vars:
        archive_source: >-
          {{
            search_archive.files |
            map(attribute='path') |
            select('match', '^.*/' + item | basename + '$') |
            first
          }}
      copy:
        remote_src: yes
        src: "{{ archive_source }}"
        dest: "{{ item }}"
      loop: "{{ search_code.files | map(attribute='path') | list }}"
      loop_control:
        label:
          Source: "{{ archive_source }}"
          Destination: "{{ item }}"

结果

PLAY [Update files from package in code wherever they are] *****************************************************************************************************************************************************************************

TASK [Capture sample data structure] ***************************************************************************************************************************************************************************************************
ok: [localhost]

TASK [Show sample data structure] ******************************************************************************************************************************************************************************************************
ok: [localhost] => {
    "msg": [
        "archive",
        "├── a_dir",
        "│   └── file2",
        "├── file1.txt",
        "├── file3",
        "└── other_dir",
        "    └── bla",
        "        └── fileX",
        "code",
        "├── dir1",
        "│   └── file1.txt",
        "├── dir2",
        "│   ├── file2",
        "│   ├── pipo",
        "│   └── toto",
        "└── dir3",
        "    └── subdir",
        "        └── file3",
        "",
        "7 directories, 9 files"
    ]
}

TASK [Find files in archive] ***********************************************************************************************************************************************************************************************************
ok: [localhost]

TASK [Find files in code matching names in archive] ************************************************************************************************************************************************************************************
ok: [localhost]

TASK [Copy files from archive to code] *************************************************************************************************************************************************************************************************
changed: [localhost] => (item={'Source': 'archive/file1.txt', 'Destination': 'code/dir1/file1.txt'})
changed: [localhost] => (item={'Source': 'archive/a_dir/file2', 'Destination': 'code/dir2/file2'})
changed: [localhost] => (item={'Source': 'archive/file3', 'Destination': 'code/dir3/subdir/file3'})

PLAY RECAP *****************************************************************************************************************************************************************************************************************************
localhost                  : ok=5    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章