#ansible
Вопрос вообще возник из того, что при клонировании крупных репозиториев вижу, что
порядок вывода на экран меняется.
Ну, чтобы не быть голословным, - конкретный пример для ansible 2.1
Набор данных:
repositories:
mediawiki_core1:
repo: https://gerrit.wikimedia.org/r/p/mediawiki/core.git
path: w1
mediawiki_core2:
repo: https://gerrit.wikimedia.org/r/p/mediawiki/core.git
path: w2
version: REL1_25
mediawiki_core3:
repo: https://gerrit.wikimedia.org/r/p/mediawiki/core.git
path: w3
Обработчик:
- name: clone repositories
git:
repo: "{{ item.value.repo }}"
dest: "/root/tests/{{ item.value.path }}/"
version: "{{ item.value.version | default('HEAD') }}"
become: true
become_user: apache
with_dict: "{{ repositories }}"
Вывод окажется таким:
TASK [abcdef : clone repositories]
changed: [server.domain.ru] => (item={'value': {u'repo':
u'https://gerrit.wikimedia.org/r/p/mediawiki/core.git', u'path':
u'w1'}, 'key': u'mediawiki_core1'})
changed: [server.domain.ru] => (item={'value': {u'repo':
u'https://gerrit.wikimedia.org/r/p/mediawiki/core.git', u'path':
u'w3'}, 'key': u'mediawiki_core3'})
changed: [server.domain.ru] => (item={'value': {u'repo':
u'https://gerrit.wikimedia.org/r/p/mediawiki/core.git', u'path':
u'w2', u'version': u'REL1_25'}, 'key': u'mediawiki_core2'})
Нужно сделать так, чтобы гарантированно выполнить последовательно задачи одну за
другой -- вне зависимости от того, сколько длится её выполнение.
Типичный пример: после того, как клонируется движок вики (очень длительная задача),
можно приступать к клонированию множества мелких репозиториев со скринами и экстеншнами.
Дополнительно, хочется навести порядок в голове и разобраться, как управлять порядком
выполнения, чтобы уметь распараллеливать задачи, если нужно, но и если нужно гарантировать,
что задачи выполнятся одна за другой в указанном порядке, то уметь выполнять их последовательно.
P.S. Что самое странное: именно в приведённом примере проблема с порядком возникает,
а вот когда запускаешь разные репозитории (первым -- тяжёлый медиавики, вторым -- небольшой
собственный репозиторий), проблема перестаёт воспроизводиться: сначала долго отрабатывает
первый таск, потом быстро пролетает второй.
В мистику не верю: это просто говорит о непонимании, как оно всё работает под капотом.
Ответы
Ответ 1
Насколько я понял гоняя допонительные тесты, дело вообще не в том, сколько по времени выполняется задача внутри dict -- а в том, что сортировка для dict не гарантирована. Об этом было в этом вопросе на большом СО. Точнее, обход with_dict проходит по dict не в том порядке, в котором я указываю элементы: идёт внутренняя сортировка по значению хеша. Для того, чтобы обходить элементы в том порядке, в котором я записал их - нужно заменять dict на items и обход делать не with_dict, а with_items. vars: with_dict_test: - { key: 'one', value: 1 } - { key: 'two', value: 2 } - { key: 'three', value: 3 } - { key: 'four', value: 4 } - { key: 'five', value: 5 } tasks: - name: with_dict test debug: msg="{{item.key}} --> {{item.value}}" with_items: "{{ with_dict_test }}" Или, точный пример, как у меня в вопросе: vars: with_dict_test: - { repo: 'url1', path: 'A', version: 'REL1_25' } - { repo: 'url2', path: 'B' } tasks: - name: with_dict test debug: msg="{{item.repo}} --> {{item.path}} -- {{ item.version | default ('HEAD') }}" with_items: "{{ with_dict_test }}" И что-то мне такая форма сильно напоминает ;) Открываем документацию, раздел Standard Loops и видим: Note that the types of items you iterate over with ‘with_items’ do not have to be simple lists of strings. If you have a list of hashes, you can reference subkeys using things like: - name: add several users user: name={{ item.name }} state=present groups={{ item.groups }} with_items: - { name: 'testuser1', groups: 'wheel' } - { name: 'testuser2', groups: 'root' } Вот так совсем хорошо: with_dict_test: - { repo: 'url1' , version: 'REL1_25' , path: 'A' } - { repo: 'url2' , path: 'B' }
Комментариев нет:
Отправить комментарий