@@ -3,6 +3,7 @@ package stage_parsers
3
3
import (
4
4
"github.com/semaphoreui/semaphore/db"
5
5
"github.com/semaphoreui/semaphore/util"
6
+ "regexp"
6
7
"strings"
7
8
)
8
9
@@ -48,6 +49,9 @@ func (p AnsibleRunningStageParser) IsEnd(currentStage *db.TaskStage, output db.T
48
49
const ansibleTaskMaker = "TASK ["
49
50
const failedTaskMaker = "fatal: ["
50
51
52
+ var newTaskMakerRE = regexp .MustCompile (`^\w+: \[` )
53
+ var fatalTaskRE = regexp .MustCompile (`^fatal: \[([^]]+)]: FAILED! => (.*)$` )
54
+
51
55
func (p AnsibleRunningStageParser ) Parse (currentStage * db.TaskStage , output db.TaskOutput , store db.Store , projectID int ) (ok bool , err error ) {
52
56
53
57
if currentStage == nil {
@@ -64,6 +68,7 @@ func (p AnsibleRunningStageParser) Parse(currentStage *db.TaskStage, output db.T
64
68
65
69
if strings .HasPrefix (line , ansibleTaskMaker ) {
66
70
p .state .Tasks ++
71
+
67
72
if p .state .CurrentFailedHost != "" {
68
73
err = store .CreateAnsibleTaskError (db.AnsibleTaskError {
69
74
TaskID : currentStage .TaskID ,
@@ -82,13 +87,40 @@ func (p AnsibleRunningStageParser) Parse(currentStage *db.TaskStage, output db.T
82
87
p .state .CurrentTask = line [len (ansibleTaskMaker ):end ]
83
88
p .state .CurrentFailedHost = ""
84
89
p .state .CurrentHostAnswer = ""
90
+
85
91
} else if strings .HasPrefix (line , failedTaskMaker ) {
86
- end := strings .Index (line , "]" )
87
- start := len (failedTaskMaker )
88
- p .state .CurrentFailedHost = line [start :end ]
89
- p .state .CurrentHostAnswer = ""
92
+
93
+ if p .state .CurrentFailedHost != "" {
94
+ err = store .CreateAnsibleTaskError (db.AnsibleTaskError {
95
+ TaskID : currentStage .TaskID ,
96
+ ProjectID : projectID ,
97
+ Host : p .state .CurrentFailedHost ,
98
+ Task : p .state .CurrentTask ,
99
+ Error : p .state .CurrentHostAnswer ,
100
+ })
101
+
102
+ if err != nil {
103
+ return
104
+ }
105
+ }
106
+
107
+ m := fatalTaskRE .FindStringSubmatch (line )
108
+ if len (m ) > 0 {
109
+ host := strings .TrimSpace (m [1 ])
110
+ msg := strings .TrimSpace (m [2 ])
111
+ p .state .CurrentFailedHost = host
112
+ p .state .CurrentHostAnswer = msg
113
+ } else {
114
+ end := strings .Index (line , "]" )
115
+ start := len (failedTaskMaker )
116
+ p .state .CurrentFailedHost = line [start :end ]
117
+ p .state .CurrentHostAnswer = ""
118
+ }
119
+
90
120
} else if p .state .CurrentFailedHost != "" {
91
- if line == "" {
121
+ m := newTaskMakerRE .FindStringSubmatch (line )
122
+ if line == "" || len (m ) > 0 {
123
+
92
124
if p .state .CurrentFailedHost != "" {
93
125
err = store .CreateAnsibleTaskError (db.AnsibleTaskError {
94
126
TaskID : currentStage .TaskID ,
@@ -104,6 +136,7 @@ func (p AnsibleRunningStageParser) Parse(currentStage *db.TaskStage, output db.T
104
136
}
105
137
p .state .CurrentFailedHost = ""
106
138
p .state .CurrentHostAnswer = ""
139
+
107
140
} else {
108
141
p .state .CurrentHostAnswer += "\n " + line
109
142
}
0 commit comments