Skip to content

Commit acba544

Browse files
committed
check function in status
1 parent 76faefe commit acba544

File tree

3 files changed

+34
-42
lines changed

3 files changed

+34
-42
lines changed

internal/orchestrator/helpers.go

Lines changed: 8 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,7 @@ import (
1919
"context"
2020
"errors"
2121
"fmt"
22-
"log/slog"
23-
"regexp"
2422
"slices"
25-
"strconv"
2623
"strings"
2724

2825
"github.com/arduino/go-paths-helper"
@@ -42,11 +39,6 @@ type AppStatusInfo struct {
4239
Status Status
4340
}
4441

45-
type containerState struct {
46-
Status Status
47-
StatusMessage string
48-
}
49-
5042
// parseAppStatus takes all the containers that matches the DockerAppLabel,
5143
// and construct a map of the state of an app and all its dependencies state.
5244
// For app that have at least 1 dependency, we calculate the overall state
@@ -59,16 +51,14 @@ type containerState struct {
5951
// starting: at least one starting
6052
func parseAppStatus(containers []container.Summary) []AppStatusInfo {
6153
apps := make([]AppStatusInfo, 0, len(containers))
62-
appsStatusMap := make(map[string][]containerState)
54+
appsStatusMap := make(map[string][]Status)
6355
for _, c := range containers {
6456
appPath, ok := c.Labels[DockerAppPathLabel]
6557
if !ok {
6658
continue
6759
}
68-
appsStatusMap[appPath] = append(appsStatusMap[appPath], containerState{
69-
Status: StatusFromDockerState(c.State),
70-
StatusMessage: c.Status,
71-
})
60+
appsStatusMap[appPath] = append(appsStatusMap[appPath], StatusFromDockerState(c.State, c.Status))
61+
7262
}
7363

7464
appendResult := func(appPath *paths.Path, status Status) {
@@ -84,31 +74,27 @@ func parseAppStatus(containers []container.Summary) []AppStatusInfo {
8474
appPath := paths.New(appPath)
8575

8676
// running: all running
87-
if !slices.ContainsFunc(s, func(v containerState) bool { return v.Status != StatusRunning }) {
77+
if !slices.ContainsFunc(s, func(v Status) bool { return v != StatusRunning }) {
8878
appendResult(appPath, StatusRunning)
8979
continue
9080
}
9181
// stopped: all stopped
92-
if !slices.ContainsFunc(s, func(v containerState) bool { return v.Status != StatusStopped }) {
82+
if !slices.ContainsFunc(s, func(v Status) bool { return v != StatusStopped }) {
9383
appendResult(appPath, StatusStopped)
9484
continue
9585
}
9686

9787
// ...else we have multiple different status we calculate the status
9888
// among the possible left: {failed, stopping, starting}
99-
if slices.ContainsFunc(s, func(v containerState) bool { return v.Status == StatusFailed }) {
100-
appendResult(appPath, StatusFailed)
101-
continue
102-
}
103-
if slices.ContainsFunc(s, func(v containerState) bool { return v.Status == StatusStopped && checkExitCode(v) }) {
89+
if slices.ContainsFunc(s, func(v Status) bool { return v == StatusFailed }) {
10490
appendResult(appPath, StatusFailed)
10591
continue
10692
}
107-
if slices.ContainsFunc(s, func(v containerState) bool { return v.Status == StatusStopping }) {
93+
if slices.ContainsFunc(s, func(v Status) bool { return v == StatusStopping }) {
10894
appendResult(appPath, StatusStopping)
10995
continue
11096
}
111-
if slices.ContainsFunc(s, func(v containerState) bool { return v.Status == StatusStarting }) {
97+
if slices.ContainsFunc(s, func(v Status) bool { return v == StatusStarting }) {
11298
appendResult(appPath, StatusStarting)
11399
continue
114100
}
@@ -265,20 +251,3 @@ func setStatusLeds(trigger LedTrigger) error {
265251
}
266252
return nil
267253
}
268-
269-
func checkExitCode(state containerState) bool {
270-
var exitCodeRegex = regexp.MustCompile(`Exited \((\d+)\)`)
271-
result := false
272-
matches := exitCodeRegex.FindStringSubmatch(state.StatusMessage)
273-
274-
exitCode, err := strconv.Atoi(matches[1])
275-
if err != nil {
276-
slog.Error("Failed to parse exit code from status message", slog.String("statusMessage", state.StatusMessage), slog.String("error", err.Error()))
277-
return false
278-
}
279-
if exitCode >= 0 && exitCode < 128 {
280-
result = true
281-
}
282-
283-
return result
284-
}

internal/orchestrator/helpers_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ func TestParseAppStatus(t *testing.T) {
7474
{
7575
name: "failed",
7676
containerState: []container.ContainerState{container.StateRestarting, container.StateExited},
77-
statusMessage: []string{"Restarting", "Exited (0)"},
77+
statusMessage: []string{"Restarting", "Exited (1)"},
7878
want: StatusFailed,
7979
},
8080
}

internal/orchestrator/status.go

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,11 @@ package orchestrator
1717

1818
import (
1919
"fmt"
20+
"regexp"
21+
"strconv"
2022

2123
"github.com/docker/docker/api/types/container"
24+
"go.bug.st/f"
2225
)
2326

2427
type Status string
@@ -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:
46+
return StatusStopped
47+
case container.StateExited:
48+
if !isExitBySignal(statusMessage) {
49+
return StatusFailed
50+
}
4351
return StatusStopped
4452
case container.StateDead:
4553
return StatusFailed
54+
4655
default:
4756
panic("unreachable")
4857
}
@@ -65,3 +74,17 @@ func (s Status) Validate() error {
6574
func (s Status) AllowedStatuses() []Status {
6675
return []Status{StatusStarting, StatusRunning, StatusStopping, StatusStopped, StatusFailed}
6776
}
77+
78+
func isExitBySignal(statusMessage string) bool {
79+
var exitCodeRegex = regexp.MustCompile(`Exited \((\d+)\)`)
80+
matches := exitCodeRegex.FindStringSubmatch(statusMessage)
81+
if len(matches) < 2 {
82+
// not matching an exit code
83+
return false
84+
}
85+
exitCode := f.Must(strconv.Atoi(matches[1]))
86+
87+
// posix exit code greater than 128+n means terminated by signal https://tldp.org/LDP/abs/html/exitcodes.html
88+
return exitCode > 128
89+
90+
}

0 commit comments

Comments
 (0)