Ansible async_status task - error: ansible_job_id "undefined variable"
Ansible async_status task - error: ansible_job_id "undefined variable"
我有一个 3 节点 ubuntu 20.04 lts - kvm - kubernetes 集群,kvm-host 也是 ubuntu 20.04 lts。我 运行 kvm-host 上的剧本。
我有以下清单摘录:
nodes:
hosts:
sea_r:
ansible_host: 192.168.122.60
spring_r:
ansible_host: 192.168.122.92
island_r:
ansible_host: 192.168.122.93
vars:
ansible_user: root
和已经尝试了很多async_status
,但总是失败,
- name: root commands
hosts: nodes
tasks:
- name: bash commands
ansible.builtin.shell: |
apt update
args:
chdir: /root
executable: /bin/bash
async: 2000
poll: 2
register: output
- name: check progress
ansible.builtin.async_status:
jid: "{{ output.ansible_job_id }}"
register: job_result
until: job_result.finished
retries: 200
delay: 5
有错误:
fatal: [sea_r]: FAILED! => {"msg": "The task
includes an option with an undefined variable.
The error was: 'dict object' has no attribute
'ansible_job_id' ...
如果我改为尝试以下方法,
- name: root commands
hosts: nodes
tasks:
- name: bash commands
ansible.builtin.shell: |
apt update
args:
chdir: /root
executable: /bin/bash
async: 2000
poll: 2
register: output
- debug: msg="{{ output.stdout_lines }}"
- debug: msg="{{ output.stderr_lines }}"
我没有收到任何错误。
还尝试了以下变体,
- name: check progress
ansible.builtin.async_status:
jid: "{{ item.ansible_job_id }}"
with_items: "{{ output }}"
register: job_result
until: job_result.finished
retries: 200
delay: 5
有人建议 as a solution to similar error。那也无济于事,我只是得到了稍微不同的错误:
fatal: [sea_r]: FAILED! => {"msg": "The task includes
an option with an undefined variable. The error
was: 'ansible.utils.unsafe_proxy.AnsibleUnsafeText
object' has no attribute 'ansible_job_id' ...
在剧本的开头和结尾,我像这样恢复和暂停我的 3 个 kvm 服务器节点:
- name: resume vms
hosts: local_vm_ctl
tasks:
- name: resume vm servers
shell: |
virsh resume kub3
virsh resume kub2
virsh resume kub1
virsh list --state-paused --state-running
args:
chdir: /home/bi
executable: /bin/bash
environment:
LIBVIRT_DEFAULT_URI: qemu:///system
register: output
- debug: msg="{{ output.stdout_lines }}"
- debug: msg="{{ output.stderr_lines }}"
等等
- name: pause vms
hosts: local_vm_ctl
tasks:
- name: suspend vm servers
shell: |
virsh suspend kub3
virsh suspend kub2
virsh suspend kub1
virsh list --state-paused --state-running
args:
chdir: /home/bi
executable: /bin/bash
environment:
LIBVIRT_DEFAULT_URI: qemu:///system
register: output
- debug: msg="{{ output.stdout_lines }}"
- debug: msg="{{ output.stderr_lines }}"
但我不明白这些戏剧与上述错误有什么关系。
任何帮助将不胜感激。
您的工作 ID 出现未定义错误,因为:
- 您在初始任务中使用
poll: X
,因此 ansible 每 X 秒连接一次以检查任务是否完成
- 当 ansible 存在那个任务并进入你的下一个
async_status
任务时,工作就完成了。并且由于您对 poll
使用了非零值,因此自动清除了异步状态缓存。
- 由于缓存被清除,作业id不再存在。
你上面的场景是为了避免你的目标在长时间的 运行ning 任务上超时,而不是为了 运行 任务并发并有一个稍后的状态检查点。对于第二个需求,你需要运行异步任务poll: 0
并自行清理缓存
有关上述概念的更多解释,请参阅文档:
我用你的上述任务做了一个例子,并将其修复为使用专用模块 apt
(请注意,你可以向模块添加一个 name
选项,其中包含一个或一系列包和ansible 会一步完成缓存更新和安装)。此外,async_status 任务的 retries * delay
应该等于或大于初始任务的 async
,如果你想确保你不会错过最后。
- name: Update apt cache
ansible.builtin.apt:
update_cache: true
async: 2000
poll: 0
register: output
- name: check progress
ansible.builtin.async_status:
jid: "{{ output.ansible_job_id }}"
register: job_result
until: job_result.finished
retries: 400
delay: 5
- name: clean async job cache
ansible.builtin.async_status:
jid: "{{ output.ansible_job_id }}"
mode: cleanup
这对于并行启动一堆持久任务更有用。这是一个无用但实用的示例:
- name: launch some loooooong tasks
shell: "{{ item }}"
loop:
- sleep 30
- sleep 20
- sleep 35
async: 100
poll: 0
register: long_cmd
- name: wait until all commands are done
async_status:
jid: "{{ item.ansible_job_id }}"
register: async_poll_result
until: async_poll_result.finished
retries: 50
delay: 2
loop: "{{ long_cmd.results }}"
- name: clean async job cache
async_status:
jid: "{{ item.ansible_job_id }}"
mode: cleanup
loop: "{{ long_cmd.results }}"
你的任务有 poll: 2
,它告诉 Ansible 每 2 秒在内部轮询一次异步作业,并 return 注册变量中的最终状态。 In order to use async_status
你应该设置 poll: 0
这样任务就不会等待作业完成。
我有一个 3 节点 ubuntu 20.04 lts - kvm - kubernetes 集群,kvm-host 也是 ubuntu 20.04 lts。我 运行 kvm-host 上的剧本。 我有以下清单摘录:
nodes:
hosts:
sea_r:
ansible_host: 192.168.122.60
spring_r:
ansible_host: 192.168.122.92
island_r:
ansible_host: 192.168.122.93
vars:
ansible_user: root
和已经尝试了很多async_status
,但总是失败,
- name: root commands
hosts: nodes
tasks:
- name: bash commands
ansible.builtin.shell: |
apt update
args:
chdir: /root
executable: /bin/bash
async: 2000
poll: 2
register: output
- name: check progress
ansible.builtin.async_status:
jid: "{{ output.ansible_job_id }}"
register: job_result
until: job_result.finished
retries: 200
delay: 5
有错误:
fatal: [sea_r]: FAILED! => {"msg": "The task
includes an option with an undefined variable.
The error was: 'dict object' has no attribute
'ansible_job_id' ...
如果我改为尝试以下方法,
- name: root commands
hosts: nodes
tasks:
- name: bash commands
ansible.builtin.shell: |
apt update
args:
chdir: /root
executable: /bin/bash
async: 2000
poll: 2
register: output
- debug: msg="{{ output.stdout_lines }}"
- debug: msg="{{ output.stderr_lines }}"
我没有收到任何错误。 还尝试了以下变体,
- name: check progress
ansible.builtin.async_status:
jid: "{{ item.ansible_job_id }}"
with_items: "{{ output }}"
register: job_result
until: job_result.finished
retries: 200
delay: 5
有人建议 as a solution to similar error。那也无济于事,我只是得到了稍微不同的错误:
fatal: [sea_r]: FAILED! => {"msg": "The task includes
an option with an undefined variable. The error
was: 'ansible.utils.unsafe_proxy.AnsibleUnsafeText
object' has no attribute 'ansible_job_id' ...
在剧本的开头和结尾,我像这样恢复和暂停我的 3 个 kvm 服务器节点:
- name: resume vms
hosts: local_vm_ctl
tasks:
- name: resume vm servers
shell: |
virsh resume kub3
virsh resume kub2
virsh resume kub1
virsh list --state-paused --state-running
args:
chdir: /home/bi
executable: /bin/bash
environment:
LIBVIRT_DEFAULT_URI: qemu:///system
register: output
- debug: msg="{{ output.stdout_lines }}"
- debug: msg="{{ output.stderr_lines }}"
等等
- name: pause vms
hosts: local_vm_ctl
tasks:
- name: suspend vm servers
shell: |
virsh suspend kub3
virsh suspend kub2
virsh suspend kub1
virsh list --state-paused --state-running
args:
chdir: /home/bi
executable: /bin/bash
environment:
LIBVIRT_DEFAULT_URI: qemu:///system
register: output
- debug: msg="{{ output.stdout_lines }}"
- debug: msg="{{ output.stderr_lines }}"
但我不明白这些戏剧与上述错误有什么关系。
任何帮助将不胜感激。
您的工作 ID 出现未定义错误,因为:
- 您在初始任务中使用
poll: X
,因此 ansible 每 X 秒连接一次以检查任务是否完成 - 当 ansible 存在那个任务并进入你的下一个
async_status
任务时,工作就完成了。并且由于您对poll
使用了非零值,因此自动清除了异步状态缓存。 - 由于缓存被清除,作业id不再存在。
你上面的场景是为了避免你的目标在长时间的 运行ning 任务上超时,而不是为了 运行 任务并发并有一个稍后的状态检查点。对于第二个需求,你需要运行异步任务poll: 0
并自行清理缓存
有关上述概念的更多解释,请参阅文档:
我用你的上述任务做了一个例子,并将其修复为使用专用模块 apt
(请注意,你可以向模块添加一个 name
选项,其中包含一个或一系列包和ansible 会一步完成缓存更新和安装)。此外,async_status 任务的 retries * delay
应该等于或大于初始任务的 async
,如果你想确保你不会错过最后。
- name: Update apt cache
ansible.builtin.apt:
update_cache: true
async: 2000
poll: 0
register: output
- name: check progress
ansible.builtin.async_status:
jid: "{{ output.ansible_job_id }}"
register: job_result
until: job_result.finished
retries: 400
delay: 5
- name: clean async job cache
ansible.builtin.async_status:
jid: "{{ output.ansible_job_id }}"
mode: cleanup
这对于并行启动一堆持久任务更有用。这是一个无用但实用的示例:
- name: launch some loooooong tasks
shell: "{{ item }}"
loop:
- sleep 30
- sleep 20
- sleep 35
async: 100
poll: 0
register: long_cmd
- name: wait until all commands are done
async_status:
jid: "{{ item.ansible_job_id }}"
register: async_poll_result
until: async_poll_result.finished
retries: 50
delay: 2
loop: "{{ long_cmd.results }}"
- name: clean async job cache
async_status:
jid: "{{ item.ansible_job_id }}"
mode: cleanup
loop: "{{ long_cmd.results }}"
你的任务有 poll: 2
,它告诉 Ansible 每 2 秒在内部轮询一次异步作业,并 return 注册变量中的最终状态。 In order to use async_status
你应该设置 poll: 0
这样任务就不会等待作业完成。