@@ -32,7 +32,9 @@ import (
32
32
)
33
33
34
34
const (
35
- dirStatus = "endpoint-status"
35
+ dirStatus = "endpoint-status"
36
+ statusUp = "up"
37
+ statusDown = "down"
36
38
)
37
39
38
40
// EndpointStatusFileReporter writes a file to the FS
@@ -55,6 +57,8 @@ type EndpointStatusFileReporter struct {
55
57
reapplyInterval time.Duration
56
58
57
59
hostname string
60
+
61
+ filesys
58
62
}
59
63
60
64
// Backoff wraps a timer-based-retry type which can be stepped.
@@ -68,6 +72,35 @@ type backoffManager struct {
68
72
newBackoffFunc func () Backoff
69
73
}
70
74
75
+ type filesys interface {
76
+ Create (name string ) (* os.File , error )
77
+ Remove (name string ) error
78
+ Mkdir (name string , perm os.FileMode ) error
79
+ ReadDir (name string ) ([]os.DirEntry , error )
80
+ }
81
+
82
+ type defaultFilesys struct {}
83
+
84
+ // Create wraps os.Create.
85
+ func (fs * defaultFilesys ) Create (name string ) (* os.File , error ) {
86
+ return os .Create (name )
87
+ }
88
+
89
+ // Remove wraps os.Remove.
90
+ func (fs * defaultFilesys ) Remove (name string ) error {
91
+ return os .Remove (name )
92
+ }
93
+
94
+ // Mkdir wraps os.Mkdir.
95
+ func (fs * defaultFilesys ) Mkdir (name string , perm os.FileMode ) error {
96
+ return os .Mkdir (name , perm )
97
+ }
98
+
99
+ // ReadDir wraps os.ReadDir.
100
+ func (fs * defaultFilesys ) ReadDir (name string ) ([]os.DirEntry , error ) {
101
+ return os .ReadDir (name )
102
+ }
103
+
71
104
// newBackoffManager creates a backoffManager which uses the
72
105
// passed func to create backoffs.
73
106
func newBackoffManager (newBackoffFunc func () Backoff ) backoffManager {
@@ -99,6 +132,7 @@ func NewEndpointStatusFileReporter(
99
132
bom : newBackoffManager (newDefaultBackoff ),
100
133
hostname : "" ,
101
134
reapplyInterval : 10 * time .Second ,
135
+ filesys : & defaultFilesys {},
102
136
}
103
137
104
138
for _ , o := range opts {
@@ -124,6 +158,13 @@ func WithHostname(hostname string) FileReporterOption {
124
158
}
125
159
}
126
160
161
+ // WithFilesys allows shimming into filesystem calls.
162
+ func WithFilesys (f filesys ) FileReporterOption {
163
+ return func (fr * EndpointStatusFileReporter ) {
164
+ fr .filesys = f
165
+ }
166
+ }
167
+
127
168
// SyncForever blocks until ctx is cancelled.
128
169
// Continuously pulls status-updates from updates C,
129
170
// and reconciles the filesystem with internal state.
@@ -245,7 +286,20 @@ func (fr *EndpointStatusFileReporter) handleEndpointUpdate(e interface{}) {
245
286
}
246
287
key := names .WorkloadEndpointIDToWorkloadEndpointKey (m .Id , fr .hostname )
247
288
fn := names .WorkloadEndpointKeyToStatusFilename (key )
248
- fr .statusDirDeltaTracker .Desired ().Add (fn )
289
+
290
+ if m .Status .Status == statusDown {
291
+ logrus .WithField ("update" , e ).Debug ("Skipping WorkloadEndpointStatusUpdate with down status" )
292
+ fr .statusDirDeltaTracker .Desired ().Delete (fn )
293
+ return
294
+ } else if m .Status .Status == statusUp {
295
+ // Explicitly checking the opposite case here (rather than fallthrough)
296
+ // in-case of a terrible failure where status is neither "up" nor "down".
297
+ logrus .WithField ("update" , e ).Debug ("Handling WorkloadEndpointUpdate with up status" )
298
+ fr .statusDirDeltaTracker .Desired ().Add (fn )
299
+ } else {
300
+ logrus .WithField ("update" , e ).Warn ("Skipping update with unrecognized status" )
301
+ }
302
+
249
303
case * proto.WorkloadEndpointStatusRemove :
250
304
if m .Id == nil {
251
305
logrus .WithField ("update" , m ).Warn ("Couldn't handle nil WorkloadEndpointStatusRemove" )
@@ -259,10 +313,11 @@ func (fr *EndpointStatusFileReporter) handleEndpointUpdate(e interface{}) {
259
313
}
260
314
}
261
315
316
+ // A sub-call of SyncForever.
262
317
// Overwrites our user-space representation of the kernel with a fresh snapshot.
263
318
func (fr * EndpointStatusFileReporter ) resyncDataplaneWithKernel () error {
264
319
// Load any pre-existing committed dataplane entries.
265
- entries , err := ensureStatusDir (fr .endpointStatusDirPrefix )
320
+ entries , err := fr . ensureStatusDir (fr .endpointStatusDirPrefix )
266
321
if err != nil {
267
322
return err
268
323
}
@@ -310,7 +365,7 @@ func (fr *EndpointStatusFileReporter) writeStatusFile(name string) error {
310
365
// Write file to dir.
311
366
logrus .WithField ("filename" , name ).Debug ("Writing endpoint-status file to status-dir" )
312
367
filename := filepath .Join (fr .endpointStatusDirPrefix , dirStatus , name )
313
- f , err := os .Create (filename )
368
+ f , err := fr . filesys .Create (filename )
314
369
if err != nil {
315
370
return err
316
371
}
@@ -319,19 +374,19 @@ func (fr *EndpointStatusFileReporter) writeStatusFile(name string) error {
319
374
320
375
func (fr * EndpointStatusFileReporter ) deleteStatusFile (name string ) error {
321
376
filename := filepath .Join (fr .endpointStatusDirPrefix , dirStatus , name )
322
- return os .Remove (filename )
377
+ return fr . filesys .Remove (filename )
323
378
}
324
379
325
380
// ensureStatusDir ensures there is a directory named "endpoint-status", within
326
381
// the parent dir specified by prefix. Attempts to create the dir if it doesn't exist.
327
382
// Returns all entries within the dir if any exist.
328
- func ensureStatusDir (prefix string ) (entries []fs.DirEntry , err error ) {
383
+ func ( fr * EndpointStatusFileReporter ) ensureStatusDir (prefix string ) (entries []fs.DirEntry , err error ) {
329
384
filename := filepath .Join (prefix , dirStatus )
330
385
331
- entries , err = os .ReadDir (filename )
386
+ entries , err = fr . filesys .ReadDir (filename )
332
387
if err != nil && errors .Is (err , fs .ErrNotExist ) {
333
388
// Discard ErrNotExist and return the result of attempting to create it.
334
- return entries , os .Mkdir (filename , fs .FileMode (0655 ))
389
+ return entries , fr . filesys .Mkdir (filename , fs .FileMode (0655 ))
335
390
}
336
391
337
392
return entries , err
0 commit comments