ansible-lint
ansible-lint copied to clipboard
--fix is breaking quotes in playbook when converting ini to yaml
Summary
When playbook is using ini formating for tasks, --fix
breaks quotes.
Issue Type
- Bug Report
OS / ENVIRONMENT
ansible-lint 24.7.0 using ansible-core:2.16.10.post0 ansible-compat:24.7.0 ruamel-yaml:0.18.6 ruamel-yaml-clib:0.2.8
ansible-lint 24.7.1.dev32 using ansible-core:2.17.3 ansible-compat:24.9.0 ruamel-yaml:0.18.6 ruamel-yaml-clib:0.2.8
You are using a pre-release version of ansible-lint.
- ansible installation method: OS package / pip (for main branch test)
- ansible-lint installation method: OS package / pip (for main branch test)
STEPS TO REPRODUCE
Create a playbook like following:
---
- name: Lint issue
hosts: localhost
connection: local
gather_facts: false
vars:
script: test_file.sh
tasks:
- name: Copy script
copy:
src="{{ script }}"
dest="/tmp/{{ script }}"
mode=0777
Run ansible-lint --fix
:
# ansible-lint playbook.yml --fix
ERROR Rule specific fix not applied for: yaml/yaml playbook.yml:13
Modified 1 files.
Passed: 0 failure(s), 0 warning(s) on 1 files. Last profile that met the validation criteria was 'production'.
Check playbook:
---
- name: Lint issue
hosts: localhost
connection: local
gather_facts: false
vars:
script: test_file.sh
tasks:
- name: Copy script
ansible.builtin.copy:
src: '"{{ script }}"'
dest: '"/tmp/{{ script }}"'
mode: "0777"
Desired Behavior
Ansible-lint should not use '
around the quotes.
Possible security bugs should be reported via email to [email protected]
Actual Behavior
Ansible-lint creates '"/tmp/{{ script }}"'
which breaks playbook.
Verbose run:
# ansible-lint playbook.yml --fix -vvvv
DEBUG Logging initialized to level 10
INFO Identified / as project root due file system root.
DEBUG Options: Options(_skip_ansible_syntax_check=False, cache_dir=PosixPath('/root/.cache/ansible-compat/e3b0c4'), colored=True, configured=True, cwd=PosixPath('/root/issue'), display_relative_path=True, exclude_paths=['.cache', '.git', '.hg', '.svn', '.tox'], format=None, lintables=['playbook.yml'], list_rules=False, list_tags=False, write_list=['all'], parseable=False, quiet=0, rulesdirs=[PosixPath('/usr/lib/python3.11/site-packages/ansiblelint/rules')], skip_list=[], tags=[], verbosity=4, warn_list=['experimental', 'jinja', 'fqcn'], mock_filters=[], mock_modules=[], mock_roles=[], loop_var_prefix=None, only_builtins_allow_collections=[], only_builtins_allow_modules=[], var_naming_pattern=None, offline=None, project_dir='/', extra_vars=None, enable_list=[], skip_action_validation=True, strict=False, rules={}, profile=None, task_name_prefix='{stem} | ', sarif_file=None, config_file=None, generate_ignore=False, rulesdir=[], use_default_rules=False, version=False, list_profiles=False, ignore_file=None, max_tasks=100, max_block_depth=20, supported_ansible_also=[])
DEBUG CWD: /root/issue
DEBUG Logging initialized to level 10
DEBUG Effective yamllint rules used: {'anchors': {'level': 'error', 'forbid-undeclared-aliases': True, 'forbid-duplicated-anchors': False, 'forbid-unused-anchors': False}, 'braces': {'level': 'error', 'forbid': False, 'min-spaces-inside': 0, 'max-spaces-inside': 1, 'min-spaces-inside-empty': -1, 'max-spaces-inside-empty': -1}, 'brackets': {'level': 'error', 'forbid': False, 'min-spaces-inside': 0, 'max-spaces-inside': 0, 'min-spaces-inside-empty': -1, 'max-spaces-inside-empty': -1}, 'colons': {'level': 'error', 'max-spaces-before': 0, 'max-spaces-after': 1}, 'commas': {'level': 'error', 'max-spaces-before': 0, 'min-spaces-after': 1, 'max-spaces-after': 1}, 'comments': {'level': 'warning', 'require-starting-space': True, 'ignore-shebangs': True, 'min-spaces-from-content': 1}, 'comments-indentation': False, 'document-end': False, 'document-start': False, 'empty-lines': {'level': 'error', 'max': 2, 'max-start': 0, 'max-end': 0}, 'empty-values': False, 'float-values': False, 'hyphens': {'level': 'error', 'max-spaces-after': 1}, 'indentation': {'level': 'error', 'spaces': 'consistent', 'indent-sequences': True, 'check-multi-line-strings': False}, 'key-duplicates': {'level': 'error', 'forbid-duplicated-merge-keys': False}, 'key-ordering': False, 'line-length': {'level': 'error', 'max': 160, 'allow-non-breakable-words': True, 'allow-non-breakable-inline-mappings': False}, 'new-line-at-end-of-file': {'level': 'error'}, 'new-lines': {'level': 'error', 'type': 'unix'}, 'octal-values': {'forbid-implicit-octal': True, 'forbid-explicit-octal': True, 'level': 'error'}, 'quoted-strings': False, 'trailing-spaces': {'level': 'error'}, 'truthy': {'level': 'warning', 'allowed-values': ['true', 'false'], 'check-keys': True}}
INFO Set ANSIBLE_LIBRARY=/root/.cache/ansible-compat/4a5028/modules:/root/.ansible/plugins/modules:/usr/share/ansible/plugins/modules
INFO Set ANSIBLE_COLLECTIONS_PATH=/root/.cache/ansible-compat/4a5028/collections:/root/.ansible/collections:/usr/share/ansible/collections:/root/.cache/ansible-compat/4a5028/collections:/root/.ansible/collections:/usr/share/ansible/collections
INFO Set ANSIBLE_ROLES_PATH=/root/.cache/ansible-compat/4a5028/roles:/root/.ansible/roles:/usr/share/ansible/roles:/etc/ansible/roles
DEBUG Effective yamllint rules used: {'anchors': {'level': 'error', 'forbid-undeclared-aliases': True, 'forbid-duplicated-anchors': False, 'forbid-unused-anchors': False}, 'braces': {'level': 'error', 'forbid': False, 'min-spaces-inside': 0, 'max-spaces-inside': 1, 'min-spaces-inside-empty': -1, 'max-spaces-inside-empty': -1}, 'brackets': {'level': 'error', 'forbid': False, 'min-spaces-inside': 0, 'max-spaces-inside': 0, 'min-spaces-inside-empty': -1, 'max-spaces-inside-empty': -1}, 'colons': {'level': 'error', 'max-spaces-before': 0, 'max-spaces-after': 1}, 'commas': {'level': 'error', 'max-spaces-before': 0, 'min-spaces-after': 1, 'max-spaces-after': 1}, 'comments': {'level': 'warning', 'require-starting-space': True, 'ignore-shebangs': True, 'min-spaces-from-content': 1}, 'comments-indentation': False, 'document-end': False, 'document-start': False, 'empty-lines': {'level': 'error', 'max': 2, 'max-start': 0, 'max-end': 0}, 'empty-values': False, 'float-values': False, 'hyphens': {'level': 'error', 'max-spaces-after': 1}, 'indentation': {'level': 'error', 'spaces': 'consistent', 'indent-sequences': True, 'check-multi-line-strings': False}, 'key-duplicates': {'level': 'error', 'forbid-duplicated-merge-keys': False}, 'key-ordering': False, 'line-length': {'level': 'error', 'max': 160, 'allow-non-breakable-words': True, 'allow-non-breakable-inline-mappings': False}, 'new-line-at-end-of-file': {'level': 'error'}, 'new-lines': {'level': 'error', 'type': 'unix'}, 'octal-values': {'forbid-implicit-octal': True, 'forbid-explicit-octal': True, 'level': 'error'}, 'quoted-strings': False, 'trailing-spaces': {'level': 'error'}, 'truthy': {'level': 'warning', 'allowed-values': ['true', 'false'], 'check-keys': True}}
DEBUG Logging initialized to level 10
DEBUG Effective yamllint rules used: {'anchors': {'level': 'error', 'forbid-undeclared-aliases': True, 'forbid-duplicated-anchors': False, 'forbid-unused-anchors': False}, 'braces': {'level': 'error', 'forbid': False, 'min-spaces-inside': 0, 'max-spaces-inside': 1, 'min-spaces-inside-empty': -1, 'max-spaces-inside-empty': -1}, 'brackets': {'level': 'error', 'forbid': False, 'min-spaces-inside': 0, 'max-spaces-inside': 0, 'min-spaces-inside-empty': -1, 'max-spaces-inside-empty': -1}, 'colons': {'level': 'error', 'max-spaces-before': 0, 'max-spaces-after': 1}, 'commas': {'level': 'error', 'max-spaces-before': 0, 'min-spaces-after': 1, 'max-spaces-after': 1}, 'comments': {'level': 'warning', 'require-starting-space': True, 'ignore-shebangs': True, 'min-spaces-from-content': 1}, 'comments-indentation': False, 'document-end': False, 'document-start': False, 'empty-lines': {'level': 'error', 'max': 2, 'max-start': 0, 'max-end': 0}, 'empty-values': False, 'float-values': False, 'hyphens': {'level': 'error', 'max-spaces-after': 1}, 'indentation': {'level': 'error', 'spaces': 'consistent', 'indent-sequences': True, 'check-multi-line-strings': False}, 'key-duplicates': {'level': 'error', 'forbid-duplicated-merge-keys': False}, 'key-ordering': False, 'line-length': {'level': 'error', 'max': 160, 'allow-non-breakable-words': True, 'allow-non-breakable-inline-mappings': False}, 'new-line-at-end-of-file': {'level': 'error'}, 'new-lines': {'level': 'error', 'type': 'unix'}, 'octal-values': {'forbid-implicit-octal': True, 'forbid-explicit-octal': True, 'level': 'error'}, 'quoted-strings': False, 'trailing-spaces': {'level': 'error'}, 'truthy': {'level': 'warning', 'allowed-values': ['true', 'false'], 'check-keys': True}}
INFO Set ANSIBLE_LIBRARY=/root/.cache/ansible-compat/4a5028/modules:/root/.ansible/plugins/modules:/usr/share/ansible/plugins/modules
INFO Set ANSIBLE_COLLECTIONS_PATH=/root/.cache/ansible-compat/4a5028/collections:/root/.ansible/collections:/usr/share/ansible/collections:/root/.cache/ansible-compat/4a5028/collections:/root/.ansible/collections:/usr/share/ansible/collections
INFO Set ANSIBLE_ROLES_PATH=/root/.cache/ansible-compat/4a5028/roles:/root/.ansible/roles:/usr/share/ansible/roles:/etc/ansible/roles
INFO Executing syntax check on playbook playbook.yml (0.51s)
DEBUG Examining playbook.yml of type playbook
DEBUG Running rule internal-error
DEBUG Running rule load-failure
DEBUG Running rule parser-error
DEBUG Running rule warning
DEBUG Running rule yaml
DEBUG Running rule args
DEBUG Running rule avoid-implicit
DEBUG Running rule command-instead-of-module
DEBUG Running rule command-instead-of-shell
DEBUG Running rule complexity
DEBUG Running rule deprecated-bare-vars
DEBUG Running rule deprecated-local-action
DEBUG Running rule deprecated-module
DEBUG Running rule fqcn
DEBUG Running rule galaxy
DEBUG Running rule ignore-errors
DEBUG Running rule inline-env-var
DEBUG Running rule jinja
DEBUG NAME 'script' (prefix='')
DEBUG NEWLINE '\n' (prefix=' ')
DEBUG ENDMARKER '' (prefix='')
DEBUG Stop.
DEBUG NAME 'script' (prefix='')
DEBUG NEWLINE '\n' (prefix='')
DEBUG ENDMARKER '' (prefix='')
DEBUG Stop.
DEBUG NAME 'script' (prefix='')
DEBUG NEWLINE '\n' (prefix=' ')
DEBUG ENDMARKER '' (prefix='')
DEBUG Stop.
DEBUG NAME 'script' (prefix='')
DEBUG NEWLINE '\n' (prefix='')
DEBUG ENDMARKER '' (prefix='')
DEBUG Stop.
DEBUG Running rule key-order
DEBUG Running rule latest
DEBUG Running rule literal-compare
DEBUG Running rule loop-var-prefix
DEBUG Running rule meta-incorrect
DEBUG Running rule meta-no-tags
DEBUG Running rule meta-runtime
DEBUG Running rule meta-video-links
DEBUG Running rule name
DEBUG Running rule no-changed-when
DEBUG Running rule no-free-form
DEBUG Running rule no-handler
DEBUG Running rule no-jinja-when
DEBUG Running rule no-relative-paths
DEBUG Running rule no-tabs
DEBUG Running rule package-latest
DEBUG Running rule partial-become
DEBUG Running rule playbook-extension
DEBUG Running rule risky-file-permissions
DEBUG Running rule risky-octal
DEBUG Running rule risky-shell-pipe
DEBUG Running rule role-name
DEBUG Running rule run-once
DEBUG Running rule sanity
DEBUG Running rule schema
DEBUG Running rule var-naming
DEBUG Begin fixing: 3 matches
DEBUG Effective yamllint rules used: {'anchors': {'level': 'error', 'forbid-undeclared-aliases': True, 'forbid-duplicated-anchors': False, 'forbid-unused-anchors': False}, 'braces': {'level': 'error', 'forbid': False, 'min-spaces-inside': 0, 'max-spaces-inside': 1, 'min-spaces-inside-empty': -1, 'max-spaces-inside-empty': -1}, 'brackets': {'level': 'error', 'forbid': False, 'min-spaces-inside': 0, 'max-spaces-inside': 0, 'min-spaces-inside-empty': -1, 'max-spaces-inside-empty': -1}, 'colons': {'level': 'error', 'max-spaces-before': 0, 'max-spaces-after': 1}, 'commas': {'level': 'error', 'max-spaces-before': 0, 'min-spaces-after': 1, 'max-spaces-after': 1}, 'comments': {'level': 'warning', 'require-starting-space': True, 'ignore-shebangs': True, 'min-spaces-from-content': 1}, 'comments-indentation': False, 'document-end': False, 'document-start': False, 'empty-lines': {'level': 'error', 'max': 2, 'max-start': 0, 'max-end': 0}, 'empty-values': False, 'float-values': False, 'hyphens': {'level': 'error', 'max-spaces-after': 1}, 'indentation': {'level': 'error', 'spaces': 'consistent', 'indent-sequences': True, 'check-multi-line-strings': False}, 'key-duplicates': {'level': 'error', 'forbid-duplicated-merge-keys': False}, 'key-ordering': False, 'line-length': {'level': 'error', 'max': 160, 'allow-non-breakable-words': True, 'allow-non-breakable-inline-mappings': False}, 'new-line-at-end-of-file': {'level': 'error'}, 'new-lines': {'level': 'error', 'type': 'unix'}, 'octal-values': {'forbid-implicit-octal': True, 'forbid-explicit-octal': True, 'level': 'error'}, 'quoted-strings': False, 'trailing-spaces': {'level': 'error'}, 'truthy': {'level': 'warning', 'allowed-values': ['true', 'false'], 'check-keys': True}}
DEBUG Applying rule specific fix for: fqcn/task playbook.yml:10
DEBUG Rule specific fix applied for: fqcn/task playbook.yml:10
DEBUG Applying rule specific fix for: no-free-form/task playbook.yml:10
DEBUG Rule specific fix applied for: no-free-form/task playbook.yml:10
DEBUG Applying rule specific fix for: yaml/yaml playbook.yml:14
ERROR Rule specific fix not applied for: yaml/yaml playbook.yml:14
DEBUG Rewriting yaml file: playbook.yml (playbook), version=(1, 1)
DEBUG Fixing: (1 of 3) (Trailing spaces) matched playbook.yml:14
DEBUG Rerunning: (Trailing spaces) matched playbook.yml:14
DEBUG Examining playbook.yml of type playbook
DEBUG Skipping rule internal-error
DEBUG Skipping rule load-failure
DEBUG Skipping rule parser-error
DEBUG Skipping rule warning
DEBUG Running rule yaml
DEBUG Skipping rule args
DEBUG Skipping rule avoid-implicit
DEBUG Skipping rule command-instead-of-module
DEBUG Skipping rule command-instead-of-shell
DEBUG Skipping rule complexity
DEBUG Skipping rule deprecated-bare-vars
DEBUG Skipping rule deprecated-local-action
DEBUG Skipping rule deprecated-module
DEBUG Skipping rule fqcn
DEBUG Skipping rule galaxy
DEBUG Skipping rule ignore-errors
DEBUG Skipping rule inline-env-var
DEBUG Skipping rule jinja
DEBUG Skipping rule key-order
DEBUG Skipping rule latest
DEBUG Skipping rule literal-compare
DEBUG Skipping rule loop-var-prefix
DEBUG Skipping rule meta-incorrect
DEBUG Skipping rule meta-no-tags
DEBUG Skipping rule meta-runtime
DEBUG Skipping rule meta-video-links
DEBUG Skipping rule name
DEBUG Skipping rule no-changed-when
DEBUG Skipping rule no-free-form
DEBUG Skipping rule no-handler
DEBUG Skipping rule no-jinja-when
DEBUG Skipping rule no-relative-paths
DEBUG Skipping rule no-tabs
DEBUG Skipping rule package-latest
DEBUG Skipping rule partial-become
DEBUG Skipping rule playbook-extension
DEBUG Skipping rule risky-file-permissions
DEBUG Skipping rule risky-octal
DEBUG Skipping rule risky-shell-pipe
DEBUG Skipping rule role-name
DEBUG Skipping rule run-once
DEBUG Skipping rule sanity
DEBUG Skipping rule schema
DEBUG Skipping rule var-naming
DEBUG Newly resolved: (Trailing spaces) matched playbook.yml:14
DEBUG Fixing: (2 of 3) (Avoid using free-form when calling module actions. (copy)) matched playbook.yml:10 Task/Handler: Copy script
DEBUG Fixed, removed: (Avoid using free-form when calling module actions. (copy)) matched playbook.yml:10 Task/Handler: Copy script
DEBUG Fixing: (3 of 3) (Use FQCN for builtin module actions (copy).) matched playbook.yml:10 Use `ansible.builtin.copy` or `ansible.legacy.copy` instead.
DEBUG Fixed, removed: (Use FQCN for builtin module actions (copy).) matched playbook.yml:10 Use `ansible.builtin.copy` or `ansible.legacy.copy` instead.
DEBUG Attempting to release lock 139813365514512 on /root/.cache/ansible-compat/e3b0c4/.lock
DEBUG Lock 139813365514512 released on /root/.cache/ansible-compat/e3b0c4/.lock
DEBUG Determined rule-profile order: {'internal-error': (0, 'min'), 'load-failure': (1, 'min'), 'parser-error': (2, 'min'), 'syntax-check': (3, 'min'), 'command-instead-of-module': (4, 'basic'), 'command-instead-of-shell': (5, 'basic'), 'deprecated-bare-vars': (6, 'basic'), 'deprecated-local-action': (7, 'basic'), 'deprecated-module': (8, 'basic'), 'inline-env-var': (9, 'basic'), 'key-order': (10, 'basic'), 'literal-compare': (11, 'basic'), 'jinja': (12, 'basic'), 'no-free-form': (13, 'basic'), 'no-jinja-when': (14, 'basic'), 'no-tabs': (15, 'basic'), 'partial-become': (16, 'basic'), 'playbook-extension': (17, 'basic'), 'role-name': (18, 'basic'), 'schema': (19, 'basic'), 'name': (20, 'basic'), 'var-naming': (21, 'basic'), 'yaml': (22, 'basic'), 'name': (23, 'moderate'), 'name': (24, 'moderate'), 'name': (25, 'moderate'), 'spell-var-name': (26, 'moderate'), 'avoid-implicit': (27, 'safety'), 'latest': (28, 'safety'), 'package-latest': (29, 'safety'), 'risky-file-permissions': (30, 'safety'), 'risky-octal': (31, 'safety'), 'risky-shell-pipe': (32, 'safety'), 'galaxy': (33, 'shared'), 'ignore-errors': (34, 'shared'), 'layout': (35, 'shared'), 'meta-incorrect': (36, 'shared'), 'meta-no-tags': (37, 'shared'), 'meta-video-links': (38, 'shared'), 'meta-version': (39, 'shared'), 'meta-runtime': (40, 'shared'), 'no-changed-when': (41, 'shared'), 'no-changelog': (42, 'shared'), 'no-handler': (43, 'shared'), 'no-relative-paths': (44, 'shared'), 'max-block-depth': (45, 'shared'), 'max-tasks': (46, 'shared'), 'unsafe-loop': (47, 'shared'), 'avoid-dot-notation': (48, 'production'), 'sanity': (49, 'production'), 'fqcn': (50, 'production'), 'import-task-no-when': (51, 'production'), 'meta-no-dependencies': (52, 'production'), 'single-entry-point': (53, 'production'), 'use-loop': (54, 'production')}
Modified 1 files.
Passed: 0 failure(s), 0 warning(s) on 1 files. Last profile that met the validation criteria was 'production'.