2015-11-23 1 views
5

окружающей среды является: анзибль 1.9.2, CentOS 6,5анзибль - with_dict: словарь - Как использовать переменные, определенные в каждом словаре, который зависит от других

Я создал роль для загрузки JAVA (.tar.gz) артефакта файлы для 3 различных версий JAVA от Artifactory. Я пытаюсь использовать функцию Ansible with_dict (вместо использования with_items).

созданы следующие файлы:

$ роли кота/Java/по умолчанию/main.yml

--- 
java_versions: 
    java7_60: 
    version: 1.7.60 
    group_path: com/oracle/jdk 
    classifier: linux-x64 
    ext: tar.gz 
    dist_file: "jdk-{{ version }}-{{ classifier }}-{{ ext }}" 
# dist_file: "jdk-{{item.value.version }}-{{ item.value.classifier }}-{{ item.value.ext }}" 
    dist_url: "{{ artifactory_url }}/{{ group_path }}/{{ version }}/{{ dist_file }}" 
# dist_url: "{{ artifactory_url }}/{{ item.value.group_path }}/{{ item.value.version }}/{{ dist_file }}" 

    java7_67: 
    version: 1.7.67 
    group_path: com/oracle/jdk 
    classifier: linux-x64 
    ext: tar.gz 
    dist_file: "jdk-{{item.value.version }}-{{ item.value.classifier }}-{{ item.value.ext }}" 
    dist_url: "{{ artifactory_url }}/{{ item.value.group_path }}/{{ item.value.version }}/{{ dist_file }}" 
    java8_45: 
    version: 1.8.45 
    group_path: com/oracle/jdk 
    classifier: linux-x64 
    ext: tar.gz 
    dist_file: "jdk-{{item.value.version }}-{{ item.value.classifier }}-{{ item.value.ext }}" 
    dist_url: "{{ artifactory_url }}/{{ item.value.group_path }}/{{ item.value.version }}/{{ dist_file }}" 

Как я могу установить или использовать dist_file или dist_url переменные, которые зависят от другие переменные, определенные в том же KEY (скажем, в KEY java7_60)?

Прямо сейчас, когда я пытаюсь либо текущий dist_file или dist_url переменных ИЛИ комментируемых из линий способа установки их (т.е. с использованием item.value.), Это не устанавливающее значения этих 2-х переменными по желанию т.е. в зависимости от других переменных версия, group_path, классификатор, ext и artifactory_url (что определено в файле по умолчанию по умолчанию/main.yml другой общей роли).

Я видел, что для использования with_dict: внутри playbook/task я должен использовать {{item.value. variable_name}} но как я могу определить переменную, которая зависит от других в пределах того же раздела KEY словаря.

Сообщение об ошибке я получаю при использовании выше словаря в следующей задаче является:

$ кошачьих роли/Java/Задачи/main.yml: сообщение

- name: Download Java/JDK Versions 
    command: wget -q "{{ item.value.dist_url }}" 
    chdir="{{ common_download_dir }}" 
    creates="{{ common_download_dir }}/{{ item.value.dist_file }}" 
    with_dict: "{{ java_versions }}" 
    become_user: "{{ build_user }}" 

Ошибки с использованием dist_file/dist_url (с текущей настройкой ролей/Java/дефолты/main.yml):

TASK: [java | Download Java/JDK Versions] ************************************* 
failed: [server01.poc.jenkins] => (item={'key': 'java7_60', 'value': {'dist_file': u'jdk-{# version #}-{# classifier #}-{# ext #}', 'ext': 'tar.gz', 'version': '1.7.60', 'dist_url': u'{# artifactory_ur #}/{# group_path #}/{# version #}/{# dist_file #}', 'group_path': 'com/oracle/jdk', 'classifier': 'linux-x64'}}) => {"changed": true, "cmd": ["wget", "-q", "{# artifactory_url #}/{# group_path #}/{# version }/{# dist_file #}"], "delta": "0:00:00.006081", "end": "2015-11-23 12:50:18.383728", "item": {"key": "java7_60", "value": {"classifier": "linux-x64", "dist_file": "jdk-{# version #}-{# classifier #}-{# ext #}, "dist_url": "{# artifactory_url #}/{# group_path #}/{# version #}/{# dist_file #}", "ext": "tar.gz", "group_path": "com/oracle/jdk", "version": "1.7.60"}}, "rc": 4, "start": "2015-11-23 12:50:18.377647", "wrnings": ["Consider using get_url module rather than running wget"]} 

Сообщения об ошибке с помощью dist_file/dist_url (с линиями которые в настоящее время закомментированные в ролях/Java/дефолты/main.yml):

TASK: [java | Download Java/JDK Versions] ************************************* 
failed: [server01.poc.jenkins] => (item={'key': 'java7_60', 'value': {'dist_file': u'jdk-{#item.value.version #}-{# item.value.classifier #}-{# item.value.ext #}', 'ext': 'tar.gz', 'version': '1.7.60' , 'dist_url': u'{# artifactory_url #}/{# item.value.group_path #}/{# item.value.version #}/{# dist_file #}', 'group_path': 'com/oracle/jdk', 'classifier': 'linux-x64'}}) => {"changed": true, "cmd": ["wget", "-q", "{# artifactory_url #}/{# item.value.group_path #}/{# item.value.version #}/{# dist_file #}"], "delta": "0:00:00.005900", "end": "2015-11-23 12:36:24.131327", "item": {"key": "java7_60", "value": {"cla ssifier": "linux-x64", "dist_file": "jdk-{#item.value.version #}-{# item.value.classifier #}-{# item.value.ext #}", "dist_url": "{# artifactory_url #}/{# item.value.group_path #}/{# item.value.version #}/{# dist_file #}", "ext": "tar.gz", "group_path": "com/oracle/jdk", "version": "1.7.60"}}, "rc": 4, "start": "2015-11-23 12:36:24.125427", "warnings": ["Consider using get_url module rather than running wget"]} 
+0

Вместо того, чтобы объединить все ваши переменные вместе в переменной 'dict_url' и ссылаться на нее в вашей задаче, было бы проще просто выполнить задачу« wget -q »{{artifactory_url}}/{{item. value.group_path}}/{{item.value.version}}/{{dist_file}} "' сам? –

+0

Спасибо за комментарий. Я пробовал это, но это заставляет задачу выглядеть немного уродливо. Даже если я это сделаю, я думаю, что проблема заключается в том, можно ли задать переменную словаря, используя другую переменную словаря в одном и том же ключе. В любом случае, похоже, проблема заключается в том, что переменные в словарной переменной не заменяются. Я пытаюсь, что ты сказал, и посмотри, работает ли это! Удивление - это способ объединить/повторно использовать переменные в разделе KEY словаря. –

+1

Я считаю, что самым простым (и, возможно, лучшим) способом было бы создание строк dist_file и dist_url в роли, а не определение его в словаре. –

ответ

2

я считаю, что лучшим способом сделать то, что вы хотите (так как я не верю, что переменные цикла могут ссылаться на себя) будет иметь ваша задача:

- name: Download Java/JDK Versions 
    command: wget -q "{{ artifactory_url }}/{{ item.value.group_path }}/{{ item.value.version }}/jdk-{{item.value.version }}-{{ item.value.classifier }}-{{ item.value.ext }}" 
    chdir="{{ common_download_dir }}" 
    creates="{{ common_download_dir }}/jdk-{{item.value.version }}-{{ item.value.classifier }}-{{ item.value.ext }}" 
    with_dict: "{{ java_versions }}" 
    become_user: "{{ build_user }}" 

по существу вручную вставить переменные в вашу задачу.

Это не очень хорошо, если вам нужно использовать переменные для нескольких задач, но в незаменимом 1.x я не думаю, что есть способ сделать это довольно. У Ansible 2.0 есть блоки, с помощью которых вы могли бы объединить несколько задач вместе над dict, и вы сможете определять переменные для всех задач в этом блоке.

+1

Ответ Bruce P - лучший вариант, когда у вас есть несколько разных версий Java и часто используются переменные. Мой ответ лучше всего, когда у вас много версий Java, но часто не используйте переменные. Единственный способ получить красивое решение, если у вас много версий Java, и часто использовать переменные, - это Ansible 2.0. –

+0

Спасибо Sepehr. Я с тобой согласен. –

3

Мне было любопытно об этом, поэтому я немного поработал, и при этом я наткнулся на this similar answer. Это только часть решения в вашем случае.

Похоже, что Ansible не позволит вам ссылаться на переменную из своего собственного определения, которое, как мне кажется, имеет смысл, поскольку оно не полностью определено. Так что-то вроде этого не будет работать, и будет на самом деле бросить несколько запутанную ошибку, когда ссылается переменная:

--- 
myvar: 
    param1: foo 
    param2: "{{ myvar['foo'] }} bar" 

Он также появляется, из собственного примера, что анзибль не позволит использовать item конструкции в переменных для ссылки на другие сложные переменные. Этот тип имеет смысл для меня, поскольку кажется, что Ansible разрешает конструкции jinja2 в переменных во время определения переменной, а не во время выполнения, когда ссылается на переменную.

Таким образом, хотя это не совсем то, что вы искали, я думаю, если вы развалитесь переменным на две части, которые вы можете получить эту работу, делая что-то вдоль этих линий:

--- 
artifactory_url: "http://path.to.jarfile" 
java_versions: 
    java7_60: 
    version: 1.7.60 
    group_path: com/oracle/jdk 
    classifier: linux-x64 
    ext: tar.gz 

java_downloads: 
    java7_60: 
    dist_url: "{{ artifactory_url }}/{{ java_versions['java7_60']['group_path'] }}/{{ java_versions['java7_60']['version'] }}/jdk-{{ java_versions['java7_60']['version'] }}-{{ java_versions['java7_60']['classifier'] }}.{{ java_versions['java7_60']['ext'] }}" 

Когда ты отлаживать java_downloads таким образом, вы получите полный URL, который вы ищете:

TASK: [debug var=item] ******************************************************** 
ok: [localhost] => (item={'key': 'java7_60', 'value': {'dist_url': u'http://path.to.jarfile/com/oracle/jdk/1.7.60/jdk-1.7.60-linux-x64.tar.gz'}}) => { 
    "item": { 
     "key": "java7_60", 
     "value": { 
      "dist_url": "http://path.to.jarfile/com/oracle/jdk/1.7.60/jdk-1.7.60-linux-x64.tar.gz" 
     } 
    }, 
    "var": { 
     "item": { 
      "key": "java7_60", 
      "value": { 
       "dist_url": "http://path.to.jarfile/com/oracle/jdk/1.7.60/jdk-1.7.60-linux-x64.tar.gz" 
      } 
     } 
    } 
} 
+0

Спасибо, Брюс. Я думаю, что это мой лучший выбор. Опять же, когда у меня будет Ansible 2.0, я думаю, это будет проще. –

1

Благодаря Bruce P и N. Sepehr я сделал следующее после принятия решения/подсказки от их ответа. Теперь моя задача - работать с несколькими инструментами (jdk, mvn, gradle, maven и т. Д.) С несколькими версиями с минимальными изменениями в файлах и без необходимости (определение 2-го словаря).

Что я сделал:

В верхнем уровне/некоторые наиболее часто встречающиеся роли по умолчанию/main.yml у меня будет следующий:

$ кошачьи ролей/some_common_global_role/по умолчанию/main.yml

--- 
a_var: giga 
other_var: fifa 

dist_file: "{{ item.value.tool }}-{{item.value.version }}-{{ item.value.classifier }}.{{ item.value.ext }}" 
dist_url: "{{ artifactory_url }}/{{ item.value.group_path }}/{{ item.value.version }}/{{ dist_file }}" 

В $ кошачьи роли/Java/по умолчанию/main.yml

--- 
tool: jdk 

java_versions: 
    java7_60: 
    version: 1.7.60 
    group_path: com/oracle/jdk 
    classifier: linux-x64 
    ext: tar.gz 
    java7_67: 
    version: 1.7.67 
    group_path: com/oracle/jdk 
    classifier: linux-x64 
    ext: tar.gz 
    java8_45: 
    version: 1.8.45 
    group_path: com/oracle/jdk 
    classifier: linux-x64 
    ext: tar.gz 

В ролях отдельных инструментов/default/main.yml я задам тот же словарь и переменную инструмента, и он загрузит несколько инструментов/версий. В этом случае, ваша некоторая общий уровня роль по умолчанию/main.yml будет выглядеть следующим образом:

--- 
dist_file: "{{ tool }}-{{item.value.version }}-{{ item.value.classifier }}.{{ item.value.ext }}" 
dist_url: "{{ artifactory_url }}/{{ item.value.group_path }}/{{ item.value.version }}/{{ dist_file }}" 

Если я использую выше подход, я могу определить «инструмент» переменный при заданных ролях // дефолтов/main.yml и он будет доступен для dist_file/dist_url.

Также вместо использования команды: wget -q "...", я могу использовать get_url (module) в Ansible.

- name: Download Java/JDK Versions 
# command: wget -q "{{ dist_url }}" 
# chdir="{{ common_download_dir }}" 
# creates="{{ common_download_dir }}/{{ dist_file }}" 
    get_url: url="{{ dist_url }}" dest="{{ common_download_dir }}" 
    become_user: "{{ build_user }}" 
    with_dict: "{{ java_versions }}" 

и убедитесь, что с удаленного компьютера вы пинговать сервер Artifactory (проверку пинг .... или файл /etc/resolv.conf для записей поиска/сервера имен), и если все выглядит хорошо, то решения, размещенные здесь, будут работать!

мне лично понравилось решение для передачи инструмента переменных (в роли/задаче) уровня (таким образом, отрицая использование определения инструмента: на уровне словаря) и не требует, чтобы определить уровень переменных индивидуального _dist_file/dist_url.

Смежные вопросы