feat(ansible): support meta end_play
Co-authored-by: Virgil <virgil@lethean.io>
This commit is contained in:
parent
709b1f5dc4
commit
692c2cf58a
2 changed files with 51 additions and 0 deletions
20
executor.go
20
executor.go
|
|
@ -2,6 +2,7 @@ package ansible
|
|||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"regexp"
|
||||
"slices"
|
||||
"strconv"
|
||||
|
|
@ -14,6 +15,8 @@ import (
|
|||
coreerr "dappco.re/go/core/log"
|
||||
)
|
||||
|
||||
var errEndPlay = errors.New("end play")
|
||||
|
||||
// Executor runs Ansible playbooks.
|
||||
//
|
||||
// Example:
|
||||
|
|
@ -159,6 +162,9 @@ func (e *Executor) runPlay(ctx context.Context, play *Play) error {
|
|||
// Execute pre_tasks
|
||||
for _, task := range play.PreTasks {
|
||||
if err := e.runTaskOnHosts(ctx, batch, &task, play); err != nil {
|
||||
if errors.Is(err, errEndPlay) {
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
|
@ -166,6 +172,9 @@ func (e *Executor) runPlay(ctx context.Context, play *Play) error {
|
|||
// Execute roles
|
||||
for _, roleRef := range play.Roles {
|
||||
if err := e.runRole(ctx, batch, &roleRef, play); err != nil {
|
||||
if errors.Is(err, errEndPlay) {
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
|
@ -173,6 +182,9 @@ func (e *Executor) runPlay(ctx context.Context, play *Play) error {
|
|||
// Execute tasks
|
||||
for _, task := range play.Tasks {
|
||||
if err := e.runTaskOnHosts(ctx, batch, &task, play); err != nil {
|
||||
if errors.Is(err, errEndPlay) {
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
|
@ -180,12 +192,18 @@ func (e *Executor) runPlay(ctx context.Context, play *Play) error {
|
|||
// Execute post_tasks
|
||||
for _, task := range play.PostTasks {
|
||||
if err := e.runTaskOnHosts(ctx, batch, &task, play); err != nil {
|
||||
if errors.Is(err, errEndPlay) {
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// Run notified handlers for this batch.
|
||||
if err := e.runNotifiedHandlers(ctx, batch, play); err != nil {
|
||||
if errors.Is(err, errEndPlay) {
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
|
@ -1518,6 +1536,8 @@ func (e *Executor) handleMetaAction(ctx context.Context, hosts []string, play *P
|
|||
switch action {
|
||||
case "flush_handlers":
|
||||
return e.runNotifiedHandlers(ctx, hosts, play)
|
||||
case "end_play":
|
||||
return errEndPlay
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -377,6 +377,37 @@ func TestExecutor_RunTaskOnHosts_Good_MetaFlushesHandlers(t *testing.T) {
|
|||
assert.Equal(t, []string{"change config", "flush handlers", "restart app"}, executed)
|
||||
}
|
||||
|
||||
func TestExecutor_RunPlay_Good_MetaEndPlayStopsRemainingTasks(t *testing.T) {
|
||||
e := NewExecutor("/tmp")
|
||||
e.SetInventoryDirect(&Inventory{
|
||||
All: &InventoryGroup{
|
||||
Hosts: map[string]*Host{
|
||||
"host1": {},
|
||||
},
|
||||
},
|
||||
})
|
||||
e.clients["host1"] = &SSHClient{}
|
||||
|
||||
gatherFacts := false
|
||||
play := &Play{
|
||||
Hosts: "all",
|
||||
GatherFacts: &gatherFacts,
|
||||
Tasks: []Task{
|
||||
{Name: "before", Module: "debug", Args: map[string]any{"msg": "before"}},
|
||||
{Name: "stop", Module: "meta", Args: map[string]any{"_raw_params": "end_play"}},
|
||||
{Name: "after", Module: "debug", Args: map[string]any{"msg": "after"}},
|
||||
},
|
||||
}
|
||||
|
||||
var executed []string
|
||||
e.OnTaskEnd = func(_ string, task *Task, _ *TaskResult) {
|
||||
executed = append(executed, task.Name)
|
||||
}
|
||||
|
||||
require.NoError(t, e.runPlay(context.Background(), play))
|
||||
assert.Equal(t, []string{"before", "stop"}, executed)
|
||||
}
|
||||
|
||||
func TestExecutor_NormalizeConditions_Good_StringSlice(t *testing.T) {
|
||||
result := normalizeConditions([]string{"cond1", "cond2"})
|
||||
assert.Equal(t, []string{"cond1", "cond2"}, result)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue