diff --git a/changelogs/fragments/extra_vars_unfrack.yml b/changelogs/fragments/extra_vars_unfrack.yml new file mode 100644 index 00000000000..5700e1fff77 --- /dev/null +++ b/changelogs/fragments/extra_vars_unfrack.yml @@ -0,0 +1,2 @@ +bugfixes: + - Ensure we get full path for extra vars into cliargs to avoid realpath issues after initial load. diff --git a/lib/ansible/cli/arguments/option_helpers.py b/lib/ansible/cli/arguments/option_helpers.py index 0e7445423bf..dc3a88b53cb 100644 --- a/lib/ansible/cli/arguments/option_helpers.py +++ b/lib/ansible/cli/arguments/option_helpers.py @@ -106,6 +106,15 @@ def unfrack_path(pathsep=False): return inner +def maybe_unfrack_path(beacon): + + def inner(value): + if value.startswith(beacon): + return beacon + unfrackpath(value[1:]) + return value + return inner + + def _git_repo_info(repo_path): """ returns a string containing git branch, commit id and commit date """ result = None @@ -345,7 +354,7 @@ def add_runas_prompt_options(parser, runas_group=None): def add_runtask_options(parser): """Add options for commands that run a task""" - parser.add_argument('-e', '--extra-vars', dest="extra_vars", action="append", + parser.add_argument('-e', '--extra-vars', dest="extra_vars", action="append", type=maybe_unfrack_path('@'), help="set additional variables as key=value or YAML/JSON, if filename prepend with @", default=[]) diff --git a/test/integration/targets/inventory/1/2/3/extra_vars_relative.yml b/test/integration/targets/inventory/1/2/3/extra_vars_relative.yml new file mode 100644 index 00000000000..fa50a5accdc --- /dev/null +++ b/test/integration/targets/inventory/1/2/3/extra_vars_relative.yml @@ -0,0 +1,19 @@ +- hosts: localhost + gather_facts: false + vars: + conditions: + - my is defined + - my == 'var' + - "'webservers' in groups" + - "'web_host.example.com' in groups['webservers']" + tasks: + - name: Make sure all is loaded + assert: + that: '{{conditions}}' + + - name: Reload inventory, forces extra vars re-eval from diff basedir + meta: refresh_inventory + + - name: Make sure all is loaded, again + assert: + that: '{{conditions}}' diff --git a/test/integration/targets/inventory/1/2/inventory.yml b/test/integration/targets/inventory/1/2/inventory.yml new file mode 100644 index 00000000000..5082cef2f2e --- /dev/null +++ b/test/integration/targets/inventory/1/2/inventory.yml @@ -0,0 +1,3 @@ +plugin: constructed +groups: + webservers: inventory_hostname.startswith('web') diff --git a/test/integration/targets/inventory/1/vars.yml b/test/integration/targets/inventory/1/vars.yml new file mode 100644 index 00000000000..c11458438c4 --- /dev/null +++ b/test/integration/targets/inventory/1/vars.yml @@ -0,0 +1 @@ +my: var diff --git a/test/integration/targets/inventory/runme.sh b/test/integration/targets/inventory/runme.sh index 7ce16cf54ef..a5e40d55525 100755 --- a/test/integration/targets/inventory/runme.sh +++ b/test/integration/targets/inventory/runme.sh @@ -88,3 +88,9 @@ fi # ensure we don't traceback on inventory due to variables with int as key ansible-inventory -i inv_with_int.yml --list "$@" + +# test in subshell relative paths work mid play for extra vars in inventory refresh +{ + cd 1/2 + ansible-playbook -e @../vars.yml -i 'web_host.example.com,' -i inventory.yml 3/extra_vars_relative.yml "$@" +}