Неожиданное поведение режима из модуля шаблона, когда режим начинается с нуля

Я не уверен, что столкнулся с ошибкой 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 или это как-то ожидаемое поведение?

Это проблема синтаксического анализа YAML, процитируйте их. 0644 для YAML — восьмеричное значение. Таким образом, вы получите int 420 (преобразование восьмеричного числа 644 в десятичное).

β.εηοιτ.βε 22.11.2022 09:26

Но это не объясняет, почему он «работает» в первой задаче, но «ломается» в цикле, верно?

Kevin C 22.11.2022 09:44

Так же как-то задокументировано template mdoule - Режим параметров "...так что Ansible получает строку и может сделать свое преобразование из строки в число."

U880D 22.11.2022 09:44

Небольшой совет для редактора: чтобы между двумя предложениями была настоящая новая строка, вы можете закончить первое предложение двумя пробелами перед новой строкой, вам не нужна эта обратная косая черта :)

β.εηοιτ.βε 22.11.2022 09:44
You must either add a leading zero so that Ansible’s YAML parser knows it is an octal number. Это именно то, что я делаю.
Kevin C 22.11.2022 09:45

Как видно из исходного описания, проблема возникает из-за loop, а не из-за самого модуля шаблона. Нам нужно будет изучить содержание item.mode дополнительно с type_debug. Кроме того, тест с mode: "{{ item.mode | quote }}"

U880D 22.11.2022 09:49

@KevinC ну, это правда, но вот что означает ошибка, которую вы получаете в деталях: github.com/ansible/ansible/issues/42563

β.εηοιτ.βε 22.11.2022 09:49
Введение в Ansible Roles
Введение в Ansible Roles
Ansible - это отличный инструмент управления конфигурацией, который можно использовать для автоматизации настройки или развертывания на большом...
1
7
70
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Как уже упоминалось в комментариях, проблема возникает из-за 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, это не ошибка, это ожидаемое поведение.

Дальнейшее чтение

Довольно странное поведение, я просто не ожидал этого вообще.

Kevin C 22.11.2022 14:01

Другие вопросы по теме