本文介绍了Ansible - with_dict: 字典 - 如何使用每个字典中定义的依赖于其他字典的变量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

环境为:Ansible 1.9.2,CentOS 6.5

我创建了一个角色来从 Artifactory 下载 3 个不同 JAVA 版本的 JAVA (.tar.gz) 工件文件.我正在尝试使用 Ansible 的 with_dict 功能(而不是使用 with_items).

创建了以下文件:

$ cat roles/java/defaults/main.yml

---java_versions:java7_60:版本:1.7.60group_path: com/oracle/jdk分类器:linux-x64分机:tar.gzdist_file: "jdk-{{ 版本 }}-{{ 分类器 }}-{{ 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:版本:1.7.67group_path: com/oracle/jdk分类器:linux-x64分机:tar.gzdist_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:版本:1.8.45group_path: com/oracle/jdk分类器:linux-x64分机:tar.gzdist_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_filedist_url 变量,这些变量取决于在同一 KEY 中定义的其他变量(比如在 KEY java7_60 中))?

现在,当我尝试当前的 dist_file 或 dist_url 变量注释掉的行设置它们的方式(即使用 item.value.)时,它没有设置这些的值根据需要设置 2 个变量,即取决于其他变量 version、group_path、classifier、extartifactory_url(在另一个常见角色的 defaults/main.yml 文件中定义)).

我看到使用 with_dict: 在剧本/任务中,我必须使用 {{ item.value.variable_name }} 但是我如何定义一个依赖于其他人的变量字典的相同 KEY 部分.

在以下任务中使用上述字典时收到的错误消息是:

$ cat roles/java/tasks/main.yml:

- 名称:下载 Java/JDK 版本命令:wget -q "{{ item.value.dist_url }}"chdir="{{ common_download_dir }}"创建="{{ common_download_dir }}/{{ item.value.dist_file }}"with_dict: "{{ java_versions }}"成为用户:{{ build_user }}"

错误消息 使用 dist_file/dist_url(当前设置在roles/java/defaults/main.yml 中):

任务:[java |下载 Java/JDK 版本] *****************************************失败:[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": ["考虑使用 get_url 模块而不是运行 wget"]}

使用 dist_file/dist_url 的

错误消息(在roles/java/defaults/main.yml中当前注释掉的行):

任务:[java |下载 Java/JDK 版本] *****************************************失败:[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": {"class 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": ["考虑使用 get_url 模块而不是运行 wget"]}
解决方案

我相信做你想做的事的最好方法(因为我不相信循环变量可以引用它们自己)是让你的任务是:

>

- 名称:下载 Java/JDK 版本命令: wget -q "{{ artifactory_url }}/{{ item.value.group_path }}/{{ item.value.version }}/jdk-{{item.value.version }}-{{ item.value.分类器 }}-{{ item.value.ext }}"chdir="{{ common_download_dir }}"created="{{ common_download_dir }}/jdk-{{item.value.version }}-{{ item.value.classifier }}-{{ item.value.ext }}"with_dict: "{{ java_versions }}"成为用户:{{ build_user }}"

基本上是手动将变量插入到您的任务中.

如果您需要将变量用于多个任务,这并不漂亮,但在 ansible 1.x 中,我认为没有办法让它变得漂亮.Ansible 2.0 具有块,您可以使用这些块通过 dict 将多个任务一起循环,并且您可以为该块中的所有任务定义变量以供使用.

Environment is: Ansible 1.9.2, CentOS 6.5

I have created a role to download JAVA (.tar.gz) artifact files for 3 different JAVA versions from Artifactory. I'm trying to use Ansible's with_dict feature (instead of using with_items).

Created the following files:

$ cat roles/java/defaults/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 }}"

How can I set or use dist_file or dist_url variables which depends upon other variables defined in the same KEY (lets say in KEY java7_60)?

Right now, when I'm trying either the current dist_file or dist_url variables OR the commented out lines way of setting them (i.e. using item.value.), it's not setting the value of these 2 variables as desired i.e. depending upon other variables version, group_path, classifier, ext and artifactory_url (which is defined in another common role's defaults/main.yml file)).

I saw that for using with_dict: within a playbook/task, I have to use {{ item.value.variable_name }} but how can I define a variable which is dependent upon others within the same KEY section of a dictionary.

The error message I'm getting while using the above dictionary in the following task is:

$ cat roles/java/tasks/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 }}"

Error message with using dist_file / dist_url (with the current setup in roles/java/defaults/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"]}

Error message with using dist_file / dist_url (with the lines which are currently commented out in roles/java/defaults/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"]}
解决方案

I believe the best way to do what you want (since I don't believe loop variables can reference themselves) would be to have your task be:

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

essentially manually inserting the variables into your task.

It's not pretty if you need to use the variables for multiple tasks, but in ansible 1.x I don't think there's a way to make it pretty. Ansible 2.0 has blocks, with which you would be able to loop multiple tasks together over a dict, and you would be able to define variables for all tasks in that block to use.

这篇关于Ansible - with_dict: 字典 - 如何使用每个字典中定义的依赖于其他字典的变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-31 11:35