fix(ansible): scope playbook_dir for nested imports
Some checks are pending
CI / auto-merge (push) Waiting to run
CI / test (push) Waiting to run
CI / auto-fix (push) Waiting to run

This commit is contained in:
Virgil 2026-04-03 16:10:15 +00:00
parent b91ad5d485
commit a80daf5494
2 changed files with 55 additions and 1 deletions

View file

@ -86,10 +86,27 @@ func (p *Parser) parsePlaybook(path string, seen map[string]bool) ([]Play, error
if importPath != "" && !pathIsAbs(importPath) {
importPath = joinPath(pathDir(path), importPath)
}
imported, err := p.parsePlaybook(importPath, seen)
savedPlaybookDir, hadPlaybookDir := p.vars["playbook_dir"]
p.vars["playbook_dir"] = pathDir(importPath)
imported, err := func() ([]Play, error) {
defer func() {
if hadPlaybookDir {
p.vars["playbook_dir"] = savedPlaybookDir
} else {
delete(p.vars, "playbook_dir")
}
}()
return p.parsePlaybook(importPath, seen)
}()
if err != nil {
return nil, coreerr.E("Parser.ParsePlaybook", sprintf("expand import_playbook %d", i), err)
}
for i := range imported {
if imported[i].Vars == nil {
imported[i].Vars = make(map[string]any)
}
imported[i].Vars["playbook_dir"] = savedPlaybookDir
}
expanded = append(expanded, imported...)
continue
}

View file

@ -185,6 +185,43 @@ func TestParser_ParsePlaybook_Good_FQCNImportPlaybook(t *testing.T) {
assert.Equal(t, "all", plays[0].Hosts)
}
func TestParser_ParsePlaybook_Good_NestedImportPlaybookDirScope(t *testing.T) {
dir := t.TempDir()
mainPath := joinPath(dir, "site.yml")
outerDir := joinPath(dir, "plays")
outerPath := joinPath(outerDir, "outer.yml")
innerDir := joinPath(outerDir, "nested")
innerPath := joinPath(innerDir, "inner.yml")
yamlMain := `---
- import_playbook: plays/outer.yml
`
yamlOuter := `---
- import_playbook: "{{ playbook_dir }}/nested/inner.yml"
`
yamlInner := `---
- name: Inner play
hosts: all
tasks:
- name: Say inner
debug:
msg: "inner"
`
require.NoError(t, os.MkdirAll(innerDir, 0755))
require.NoError(t, writeTestFile(mainPath, []byte(yamlMain), 0644))
require.NoError(t, writeTestFile(outerPath, []byte(yamlOuter), 0644))
require.NoError(t, writeTestFile(innerPath, []byte(yamlInner), 0644))
p := NewParser(dir)
plays, err := p.ParsePlaybook("site.yml")
require.NoError(t, err)
require.Len(t, plays, 1)
assert.Equal(t, "Inner play", plays[0].Name)
require.NotNil(t, plays[0].Vars)
assert.Equal(t, dir, plays[0].Vars["playbook_dir"])
}
func TestParser_ParsePlaybook_Good_WithVars(t *testing.T) {
dir := t.TempDir()
path := joinPath(dir, "playbook.yml")