@@ -17,6 +17,9 @@ package orchestrator
1717
1818import (
1919 "fmt"
20+ "log/slog"
21+ "regexp"
22+ "strconv"
2023
2124 "github.com/docker/docker/api/types/container"
2225)
@@ -31,18 +34,24 @@ const (
3134 StatusFailed Status = "failed"
3235)
3336
34- func StatusFromDockerState (s container.ContainerState ) Status {
37+ func StatusFromDockerState (s container.ContainerState , statusMessage string ) Status {
3538 switch s {
3639 case container .StateRunning :
3740 return StatusRunning
3841 case container .StateRestarting :
3942 return StatusStarting
4043 case container .StateRemoving :
4144 return StatusStopping
42- case container .StateCreated , container .StateExited , container .StatePaused :
45+ case container .StateCreated , container .StatePaused , container .StateExited :
46+ if code , err := parseExitCode (statusMessage ); err != nil {
47+ slog .Warn ("Failed to parse exit code from status message" , slog .String ("statusMessage" , statusMessage ), slog .String ("error" , err .Error ()))
48+ } else if code >= 0 && code < 128 {
49+ return StatusFailed
50+ }
4351 return StatusStopped
4452 case container .StateDead :
4553 return StatusFailed
54+
4655 default :
4756 panic ("unreachable" )
4857 }
@@ -65,3 +74,14 @@ func (s Status) Validate() error {
6574func (s Status ) AllowedStatuses () []Status {
6675 return []Status {StatusStarting , StatusRunning , StatusStopping , StatusStopped , StatusFailed }
6776}
77+
78+ func parseExitCode (statusMessage string ) (int , error ) {
79+ var exitCodeRegex = regexp .MustCompile (`Exited \((\d+)\)` )
80+ matches := exitCodeRegex .FindStringSubmatch (statusMessage )
81+
82+ exitCode , err := strconv .Atoi (matches [1 ])
83+ if err != nil {
84+ return - 1 , fmt .Errorf ("failed to parse exit code from status message: %w" , err )
85+ }
86+ return exitCode , nil
87+ }
0 commit comments