Ansible - Найти, используя зарегистрированное значение переменной - PullRequest
1 голос
/ 26 апреля 2020

Я пытаюсь добиться здесь, как показано ниже:

  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') }}"

Здесь мне нужно использовать поиск, чтобы найти файлы в каталоге / 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, которые мне нужно заменить, точно такие же

1 Ответ

1 голос
/ 27 апреля 2020

Если я правильно понял, вот возможный способ справиться с тем, что вы пытаетесь сделать. В приведенном ниже примере я удалил разархивированную работу, поскольку она не находится на критическом пути.

Прохождение Playbook

  • Я создал два каталога с примерами. Первые две задачи предназначены только для того, чтобы дополнительно показать вам эту структуру теста: каталог

    1. и archive, содержащий 4 файла в случайных каталогах. Один из них отсутствует в целевом каталоге
    2. a code, содержащем несколько файлов случайных каталогов. 3 файла имеют те же базовые имена, что и другие файлы, найденные в archive.
  • Первая задача find идентична вашей и регистрирует результат с подробным описанием всех файлов в archive dir.

  • Для второй задачи find в каталоге code ключевым моментом является передача в качестве параметра patterns списка базовых имен из первого поиск, который вы можете получить с помощью выражения:

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

    Мы можем детализировать это как: получить files список из нашего архива find результат, извлечь только атрибут path, применить basename фильтр для каждого элемента списка и возврат списка.

  • Для последнего задания я использовал copy модуль . Мой пример работает на localhost, но так как ваш, вероятно, будет работать на удаленной цели, необходимо установить remote_src (или файлы будут извлечены из контроллера).

    l oop выполняется на результат предыдущего задания, поэтому мы получаем только соответствующие файлы в каталоге кода как dest. Чтобы выбрать src, мы ищем соответствующие файлы в папке архива со следующим выражением:

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

    Фильтр выбора select применяет match test для каждого пути в списке, выбирая только элементы, заканчивающиеся текущим базовым именем пути кода. Фильтр 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   
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...