@@ -2,6 +2,7 @@ package healthcheck
2
2
3
3
import (
4
4
"context"
5
+ "sort"
5
6
"time"
6
7
7
8
"golang.org/x/mod/semver"
@@ -26,7 +27,13 @@ type ProvisionerDaemonsReport struct {
26
27
Dismissed bool `json:"dismissed"`
27
28
Error * string `json:"error"`
28
29
29
- ProvisionerDaemons []codersdk.ProvisionerDaemon `json:"provisioner_daemons"`
30
+ Items []ProvisionerDaemonsReportItem `json:"items"`
31
+ }
32
+
33
+ // @typescript-generate ProvisionerDaemonsReportItem
34
+ type ProvisionerDaemonsReportItem struct {
35
+ codersdk.ProvisionerDaemon `json:"provisioner_daemon"`
36
+ Warnings []health.Message `json:"warnings"`
30
37
}
31
38
32
39
type ProvisionerDaemonsReportDeps struct {
@@ -47,7 +54,7 @@ type ProvisionerDaemonsStore interface {
47
54
}
48
55
49
56
func (r * ProvisionerDaemonsReport ) Run (ctx context.Context , opts * ProvisionerDaemonsReportDeps ) {
50
- r .ProvisionerDaemons = make ([]codersdk. ProvisionerDaemon , 0 )
57
+ r .Items = make ([]ProvisionerDaemonsReportItem , 0 )
51
58
r .Severity = health .SeverityOK
52
59
r .Warnings = make ([]health.Message , 0 )
53
60
r .Dismissed = opts .Dismissed
@@ -86,6 +93,12 @@ func (r *ProvisionerDaemonsReport) Run(ctx context.Context, opts *ProvisionerDae
86
93
r .Error = ptr .Ref ("error fetching provisioner daemons: " + err .Error ())
87
94
return
88
95
}
96
+
97
+ // Ensure stable order for display and for tests
98
+ sort .Slice (daemons , func (i , j int ) bool {
99
+ return daemons [i ].Name < daemons [j ].Name
100
+ })
101
+
89
102
for _ , daemon := range daemons {
90
103
// Daemon never connected, skip.
91
104
if ! daemon .LastSeenAt .Valid {
@@ -96,19 +109,24 @@ func (r *ProvisionerDaemonsReport) Run(ctx context.Context, opts *ProvisionerDae
96
109
continue
97
110
}
98
111
99
- r .ProvisionerDaemons = append (r .ProvisionerDaemons , db2sdk .ProvisionerDaemon (daemon ))
112
+ it := ProvisionerDaemonsReportItem {
113
+ ProvisionerDaemon : db2sdk .ProvisionerDaemon (daemon ),
114
+ Warnings : make ([]health.Message , 0 ),
115
+ }
100
116
101
117
// For release versions, just check MAJOR.MINOR and ignore patch.
102
118
if ! semver .IsValid (daemon .Version ) {
103
119
if r .Severity .Value () < health .SeverityError .Value () {
104
120
r .Severity = health .SeverityError
105
121
}
106
- r .Warnings = append (r .Warnings , health .Messagef (health .CodeUnknown , "Provisioner daemon %q reports invalid version %q" , opts .CurrentVersion , daemon .Version ))
122
+ r .Warnings = append (r .Warnings , health .Messagef (health .CodeUnknown , "Some provisioner daemons report invalid version information." ))
123
+ it .Warnings = append (it .Warnings , health .Messagef (health .CodeUnknown , "Invalid version %q" , daemon .Version ))
107
124
} else if ! buildinfo .VersionsMatch (opts .CurrentVersion , daemon .Version ) {
108
125
if r .Severity .Value () < health .SeverityWarning .Value () {
109
126
r .Severity = health .SeverityWarning
110
127
}
111
- r .Warnings = append (r .Warnings , health .Messagef (health .CodeProvisionerDaemonVersionMismatch , "Provisioner daemon %q has outdated version %q" , daemon .Name , daemon .Version ))
128
+ r .Warnings = append (r .Warnings , health .Messagef (health .CodeProvisionerDaemonVersionMismatch , "Some provisioner daemons report mismatched versions." ))
129
+ it .Warnings = append (it .Warnings , health .Messagef (health .CodeProvisionerDaemonVersionMismatch , "Mismatched version %q" , daemon .Version ))
112
130
}
113
131
114
132
// Provisioner daemon API version follows different rules; we just want to check the major API version and
@@ -119,16 +137,20 @@ func (r *ProvisionerDaemonsReport) Run(ctx context.Context, opts *ProvisionerDae
119
137
if r .Severity .Value () < health .SeverityError .Value () {
120
138
r .Severity = health .SeverityError
121
139
}
122
- r .Warnings = append (r .Warnings , health .Messagef (health .CodeUnknown , "Provisioner daemon %q reports invalid API version: %s" , daemon .Name , err .Error ()))
140
+ r .Warnings = append (r .Warnings , health .Messagef (health .CodeUnknown , "Some provisioner daemons report invalid API version information." ))
141
+ it .Warnings = append (it .Warnings , health .Messagef (health .CodeUnknown , "Invalid API version: %s" , err .Error ())) // contains version string
123
142
} else if maj != opts .CurrentAPIMajorVersion {
124
143
if r .Severity .Value () < health .SeverityWarning .Value () {
125
144
r .Severity = health .SeverityWarning
126
145
}
127
- r .Warnings = append (r .Warnings , health .Messagef (health .CodeProvisionerDaemonAPIMajorVersionDeprecated , "Provisioner daemon %q reports deprecated major API version %d. Consider upgrading!" , daemon .Name , provisionersdk .CurrentMajor ))
146
+ r .Warnings = append (r .Warnings , health .Messagef (health .CodeProvisionerDaemonAPIMajorVersionDeprecated , "Some provisioner daemons report deprecated major API versions. Consider upgrading!" ))
147
+ it .Warnings = append (it .Warnings , health .Messagef (health .CodeProvisionerDaemonAPIMajorVersionDeprecated , "Deprecated major API version %d." , provisionersdk .CurrentMajor ))
128
148
}
149
+
150
+ r .Items = append (r .Items , it )
129
151
}
130
152
131
- if len (r .ProvisionerDaemons ) == 0 {
153
+ if len (r .Items ) == 0 {
132
154
r .Severity = health .SeverityError
133
155
r .Error = ptr .Ref ("No active provisioner daemons found!" )
134
156
return
0 commit comments