Я не уверен, что столкнулся с ошибкой Ansible. Я использую эту версию Ansible:
ansible [core 2.13.4]
...
python version = 3.8.9 (default, Apr 13 2022, 08:48:07) [Clang 13.1.6 (clang-1316.0.21.2.5)]
jinja version = 3.1.2
libyaml = True
Что-то странное происходит, когда я выполняю эти задачи:
- name: template a file
template:
src: test.j2
dest: /tmp/one
owner: root
group: root
mode: 0775
- name: template 2 files in a loop
template:
src: test.j2
dest: "{{ item.dest }}"
owner: root
group: root
mode: "{{ item.mode }}"
loop:
- dest: /tmp/two
mode: 0775
- dest: /tmp/three
mode: 0644
В первой задаче режим на диске стоит 0775
, проблем нет.
Теперь для второй задачи Ansible выводит следующее:
failed: [vm-local-1] (item = {'dest': '/tmp/one', 'mode': 509}) => changed=false
ansible_loop_var: item
checksum: 4678e30d172cb68ff1dab229babb736671d75d26
details: 'bad symbolic permission for mode: 509'
gid: 0
group: root
item:
dest: /tmp/one
mode: 509
mode: '0775'
msg: mode must be in octal or symbolic form
owner: root
path: /tmp/one
secontext: unconfined_u:object_r:user_home_t:s0
size: 12
state: file
uid: 0
ok: [vm-local-1] => (item = {'dest': '/tmp/two', 'mode': 420})
Этого не происходит, когда значения mode
указаны в кавычках.
Я столкнулся с ошибкой Ansible или это как-то ожидаемое поведение?
Но это не объясняет, почему он «работает» в первой задаче, но «ломается» в цикле, верно?
Так же как-то задокументировано template mdoule - Режим параметров "...так что Ansible получает строку и может сделать свое преобразование из строки в число."
Небольшой совет для редактора: чтобы между двумя предложениями была настоящая новая строка, вы можете закончить первое предложение двумя пробелами перед новой строкой, вам не нужна эта обратная косая черта :)
You must either add a leading zero so that Ansible’s YAML parser knows it is an octal number
. Это именно то, что я делаю.
Как видно из исходного описания, проблема возникает из-за loop
, а не из-за самого модуля шаблона. Нам нужно будет изучить содержание item.mode
дополнительно с type_debug
. Кроме того, тест с mode: "{{ item.mode | quote }}"
@KevinC ну, это правда, но вот что означает ошибка, которую вы получаете в деталях: github.com/ansible/ansible/issues/42563
Как уже упоминалось в комментариях, проблема возникает из-за loop
и парсера YAML.
---
- hosts: localhost
become: false
gather_facts: false
tasks:
- name: Type debug
debug:
msg: "item.mode is {{ item.mode }} of type {{ item.mode | type_debug }}"
loop:
- dest: /tmp/two
mode: 0775
- dest: /tmp/three
mode: 0644
приведет к выводу
TASK [Type debug] *************************************************
ok: [localhost] => (item = {u'dest': u'/tmp/two', u'mode': 509}) =>
msg: item.mode is 509 of type int
ok: [localhost] => (item = {u'dest': u'/tmp/three', u'mode': 420}) =>
msg: item.mode is 420 of type int
При этом цитируемые значения для mode
в loop
приведут к
TASK [Type debug] *****************************************************
ok: [localhost] => (item = {u'dest': u'/tmp/two', u'mode': u'0775'}) =>
msg: item.mode is 0775 of type AnsibleUnicode
ok: [localhost] => (item = {u'dest': u'/tmp/three', u'mode': u'0644'}) =>
msg: item.mode is 0644 of type AnsibleUnicode
и
«Ansible получает строку и может самостоятельно преобразовать строку в число».
Вы должны удалить начальные нули, что приведет к выводу
TASK [Type debug] *************************************************
ok: [localhost] => (item = {u'dest': u'/tmp/two', u'mode': 775}) =>
msg: item.mode is 775 of type int
ok: [localhost] => (item = {u'dest': u'/tmp/three', u'mode': 644}) =>
msg: item.mode is 644 of type int
и чтобы избежать нежелательного преобразования типов.
Я столкнулся с ошибкой Ansible или это как-то ожидаемое поведение?
Подводя итог, это вызвано ведущими нулями в переменных loop
, это не ошибка, это ожидаемое поведение.
Дальнейшее чтение
Довольно странное поведение, я просто не ожидал этого вообще.
Это проблема синтаксического анализа YAML, процитируйте их.
0644
для YAML — восьмеричное значение. Таким образом, вы получите int 420 (преобразование восьмеричного числа 644 в десятичное).