[英]Ansible - Read dict items from file and use with loop
I am trying to take this effort a little further and want to download multiple files from BitBucket having different parent directories.我试图把这种努力远一点,想从不同的父目录到位桶下载多个文件。 So I am trying to use the below script.
所以我试图使用下面的脚本。
I want to put the mappings in a separate file and read it into the script, so that at subsequent times, I can just update that file, without having to touch the script.我想将映射放在一个单独的文件中并将其读入脚本,以便在随后的时间,我可以只更新该文件,而无需触及脚本。
- name: Download connector scripts
get_url:
url: "http://bbserver:7990/projects/myproject/repos/myrepo/raw/{{ item.filename }}?at=refs%2Fheads%2Fmaster"
dest: "{{ item.dest }}"
url_username: '{{ bb_username }}'
url_password: '{{ bb_password }}'
force_basic_auth: yes
loop: "{{ lookup('file', 'scriptnamesnpaths.txt').splitlines() }}"
register: showdlstatus
become: yes
become_user: '{{ bb_username }}'
- debug: var=showdlstatus
And my scriptnamesnpaths.txt
looks like this我的
scriptnamesnpaths.txt
看起来像这样
{filename: 'scripts/dir1/script1.sh', dest: "/scripts/dir1/"}
{filename: 'scripts/dir1/script2.sh', dest: "/scripts/dir1/"}
{filename: 'scripts/dir2/script3.sh', dest: "/scripts/dir2/"}
{filename: 'releases/file1.json', dest: "/scripts/releases/"}
{filename: 'releases/file2.json', dest: "/scripts/releases/"}
I basically want to download different scripts from different paths in bitbucket to different locations on the server.我基本上想从 bitbucket 中的不同路径下载不同的脚本到服务器上的不同位置。
The error I am getting with this construct is我用这个构造得到的错误是
{"msg": "The task includes an option with an undefined variable.
The error was: 'ansible.utils.unsafe_proxy.AnsibleUnsafeText object' has no attribute 'filename'
Which part am I doing wrong or missing?我做错或遗漏了哪一部分? I also tried with
loop: "{{ lookup('dict', 'scriptnamesnpaths.txt').splitlines() }}"
我也尝试过
loop: "{{ lookup('dict', 'scriptnamesnpaths.txt').splitlines() }}"
But get error about dict definition.但是得到关于 dict 定义的错误。
Any pointers or help is appreciated.任何指针或帮助表示赞赏。
Thank you谢谢
Rather than using a file
lookup, it might be easiest just to make a group_vars file so that Ansible reads it for you automatically.与其使用
file
查找, 不如创建一个group_vars文件,以便 Ansible 自动为您读取它可能是最简单的。
That is, if you create a file groups_vars/all.yml
with this content:也就是说,如果您使用以下内容创建文件
groups_vars/all.yml
:
connector_scripts:
- {filename: 'scripts/dir1/script1.sh', dest: "/scripts/dir1/"}
- {filename: 'scripts/dir1/script2.sh', dest: "/scripts/dir1/"}
- {filename: 'scripts/dir2/script3.sh', dest: "/scripts/dir2/"}
- {filename: 'releases/file1.json', dest: "/scripts/releases/"}
- {filename: 'releases/file2.json', dest: "/scripts/releases/"}
You could then write your task like this:然后你可以这样写你的任务:
- name: Download connector scripts
get_url:
url: "http://bbserver:7990/projects/myproject/repos/myrepo/raw/{{ item.filename }}?at=refs%2Fheads%2Fmaster"
dest: "{{ item.dest }}"
url_username: '{{ bb_username }}'
url_password: '{{ bb_password }}'
force_basic_auth: yes
loop: "{{ connector_scripts }}"
register: showdlstatus
become: yes
become_user: '{{ bb_username }}'
If you really want to use a file
lookup, you'll need to deal with the fact that for each iteration of your loop
, the variable item
is a string .如果你真的想用一个
file
查找,你需要处理的事实,你的每一次迭代loop
中,变量item
是一个字符串。 You can't ask for something like item.filename
because a string doesn't have an attribute filename
(which is the source of the error you're seeing).您不能要求诸如
item.filename
类的item.filename
因为字符串没有属性filename
(这是您看到的错误的来源)。 You would need to de-serialize each line before using it, for example:您需要在使用前反序列化每一行,例如:
- name: Download connector scripts
get_url:
url: "http://bbserver:7990/projects/myproject/repos/myrepo/raw/{{ (item|from_yaml).filename }}?at=refs%2Fheads%2Fmaster"
dest: "{{ (item|from_yaml).dest }}"
url_username: '{{ bb_username }}'
url_password: '{{ bb_password }}'
force_basic_auth: yes
loop: "{{ connector_scripts }}"
register: showdlstatus
become: yes
become_user: '{{ bb_username }}'
You could simplify that a bit by moving the from_yaml
call to a vars
section so you only have to do it once:您可以通过将
from_yaml
调用移动到vars
部分来稍微简化一下,这样您只需执行一次:
- name: Download connector scripts
get_url:
url: "http://bbserver:7990/projects/myproject/repos/myrepo/raw/{{ item_converted.filename }}?at=refs%2Fheads%2Fmaster"
dest: "{{ item_converted.dest }}"
url_username: '{{ bb_username }}'
url_password: '{{ bb_password }}'
force_basic_auth: yes
vars:
item_converted: "{{ item|from_yaml }}"
loop: "{{ connector_scripts }}"
register: showdlstatus
become: yes
become_user: '{{ bb_username }}'
...but I think it's much easier to simply use the first solution and drop a file into group_vars
. ...但我认为简单地使用第一个解决方案并将文件放入
group_vars
。
Is there a particular reason for favoring putting the filenames/destinations in a script rather than the task?是否有特别的理由倾向于将文件名/目标放在脚本中而不是任务中? This would be a simplified version of the task with vars included in it:
这将是包含 vars 的任务的简化版本:
- name: Download connector scripts
get_url:
url: "http://example.com/{{ item.key }}"
dest: "{{ item.value }}"
loop: "{{ files | dict2items }}"
vars:
files:
filename1: "/path/to/dest/dir/"
filename2: "/path/to/dest/dir/"
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.