Skip to content

Commit 4c2a20a

Browse files
committed
Fixed file watcher not disabling correctly
1 parent 3c93362 commit 4c2a20a

File tree

8 files changed

+98
-53
lines changed

8 files changed

+98
-53
lines changed

internal/file/file_manager_service.go

Lines changed: 8 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -102,8 +102,6 @@ type FileManagerService struct {
102102
fileServiceOperator fileServiceOperatorInterface
103103
// map of files and the actions performed on them during config apply
104104
fileActions map[string]*model.FileCache // key is file path
105-
// map of the contents of files which have been updated or deleted during config apply, used during rollback
106-
rollbackFileContents map[string][]byte // key is file path
107105
// map of the files currently on disk, used to determine the file action during config apply
108106
currentFilesOnDisk map[string]*mpi.File // key is file path
109107
previousManifestFiles map[string]*model.ManifestFile
@@ -123,7 +121,6 @@ func NewFileManagerService(fileServiceClient mpi.FileServiceClient, agentConfig
123121
fileOperator: NewFileOperator(manifestLock),
124122
fileServiceOperator: NewFileServiceOperator(agentConfig, fileServiceClient, manifestLock),
125123
fileActions: make(map[string]*model.FileCache),
126-
rollbackFileContents: make(map[string][]byte),
127124
currentFilesOnDisk: make(map[string]*mpi.File),
128125
previousManifestFiles: make(map[string]*model.ManifestFile),
129126
rollbackManifest: true,
@@ -182,15 +179,14 @@ func (fms *FileManagerService) ConfigApply(ctx context.Context,
182179
return model.NoChange, nil
183180
}
184181

185-
// fms.rollbackFileContents = fileContent
186182
fms.fileActions = diffFiles
187183

188-
fms.tempConfigDir, configTempErr = fms.createTempConfigDirectory(ctx, "config")
184+
fms.tempConfigDir, configTempErr = fms.createTempConfigDirectory("config")
189185
if configTempErr != nil {
190186
return model.Error, configTempErr
191187
}
192188

193-
fms.tempRollbackDir, rollbackTempErr = fms.createTempConfigDirectory(ctx, "rollback")
189+
fms.tempRollbackDir, rollbackTempErr = fms.createTempConfigDirectory("rollback")
194190
if rollbackTempErr != nil {
195191
return model.Error, rollbackTempErr
196192
}
@@ -245,7 +241,6 @@ func (fms *FileManagerService) RollbackTempFiles(ctx context.Context) error {
245241

246242
func (fms *FileManagerService) ClearCache() {
247243
slog.Debug("Clearing cache and temp files after config apply")
248-
clear(fms.rollbackFileContents)
249244
clear(fms.fileActions)
250245
clear(fms.previousManifestFiles)
251246

@@ -258,8 +253,6 @@ func (fms *FileManagerService) ClearCache() {
258253
if rollbackErr != nil {
259254
slog.Error("error removing temp rollback directory", "path", fms.tempRollbackDir, "err", rollbackErr)
260255
}
261-
262-
slog.Info("Cleaned up temp files")
263256
}
264257

265258
//nolint:revive,cyclop // cognitive-complexity of 13 max is 12, loop is needed cant be broken up
@@ -290,7 +283,6 @@ func (fms *FileManagerService) Rollback(ctx context.Context, instanceID string)
290283
return fmt.Errorf("failed to create directories for %s: %w", fileName, err)
291284
}
292285

293-
slog.InfoContext(ctx, "Moving files during rollback")
294286
moveErr := os.Rename(tempFilePath, fileName)
295287
if moveErr != nil {
296288
return fmt.Errorf("failed to rename file, %s to %s: %w", tempFilePath, fileName, moveErr)
@@ -407,6 +399,11 @@ func (fms *FileManagerService) DetermineFileActions(
407399
for fileName, manifestFile := range filesMap {
408400
_, exists := modifiedFiles[fileName]
409401

402+
if _, err := os.Stat(fileName); os.IsNotExist(err) {
403+
slog.DebugContext(ctx, "File already deleted, skipping", "file", fileName)
404+
continue
405+
}
406+
410407
if !exists {
411408
fileDiff[fileName] = &model.FileCache{
412409
File: manifestFile,
@@ -697,17 +694,11 @@ func (fms *FileManagerService) convertToFile(manifestFile *model.ManifestFile) *
697694
}
698695
}
699696

700-
func (fms *FileManagerService) createTempConfigDirectory(ctx context.Context, pattern string) (string, error) {
697+
func (fms *FileManagerService) createTempConfigDirectory(pattern string) (string, error) {
701698
tempDir, tempDirError := os.MkdirTemp(fms.configPath, pattern)
702699
if tempDirError != nil {
703700
return "", fmt.Errorf("failed creating temp config directory: %w", tempDirError)
704701
}
705-
defer func(path string) {
706-
err := os.RemoveAll(path)
707-
if err != nil {
708-
slog.ErrorContext(ctx, "error removing temp config directory", "path", path, "err", err)
709-
}
710-
}(tempDir)
711702

712703
return tempDir, nil
713704
}

internal/file/file_manager_service_test.go

Lines changed: 61 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ func TestFileManagerService_ConfigApply_Add(t *testing.T) {
5959
agentConfig.AllowedDirectories = []string{tempDir}
6060

6161
fileManagerService := NewFileManagerService(fakeFileServiceClient, agentConfig, &sync.RWMutex{})
62+
fileManagerService.configPath = filepath.Dir(filePath)
6263
fileManagerService.agentConfig.LibDir = manifestDirPath
6364
fileManagerService.manifestFilePath = manifestFilePath
6465

@@ -108,6 +109,7 @@ func TestFileManagerService_ConfigApply_Add_LargeFile(t *testing.T) {
108109
agentConfig.AllowedDirectories = []string{tempDir}
109110
fileManagerService := NewFileManagerService(fakeFileServiceClient, agentConfig, &sync.RWMutex{})
110111
fileManagerService.agentConfig.LibDir = manifestDirPath
112+
fileManagerService.configPath = filepath.Dir(filePath)
111113
fileManagerService.manifestFilePath = manifestFilePath
112114

113115
request := protos.CreateConfigApplyRequest(overview)
@@ -168,6 +170,7 @@ func TestFileManagerService_ConfigApply_Update(t *testing.T) {
168170

169171
fileManagerService := NewFileManagerService(fakeFileServiceClient, agentConfig, &sync.RWMutex{})
170172
fileManagerService.agentConfig.LibDir = manifestDirPath
173+
fileManagerService.configPath = filepath.Dir(tempFile.Name())
171174
fileManagerService.manifestFilePath = manifestFilePath
172175
err := fileManagerService.UpdateCurrentFilesOnDisk(ctx, filesOnDisk, false)
173176
require.NoError(t, err)
@@ -179,7 +182,11 @@ func TestFileManagerService_ConfigApply_Update(t *testing.T) {
179182
data, readErr := os.ReadFile(tempFile.Name())
180183
require.NoError(t, readErr)
181184
assert.Equal(t, fileContent, data)
182-
assert.Equal(t, fileManagerService.rollbackFileContents[tempFile.Name()], previousFileContent)
185+
186+
content, err := os.ReadFile(fileManagerService.tempRollbackDir + tempFile.Name())
187+
require.NoError(t, err)
188+
assert.Equal(t, previousFileContent, content)
189+
183190
assert.Equal(t, fileManagerService.fileActions[tempFile.Name()].File, overview.GetFiles()[0])
184191
assert.True(t, fileManagerService.rollbackManifest)
185192
}
@@ -219,6 +226,7 @@ func TestFileManagerService_ConfigApply_Delete(t *testing.T) {
219226
fileManagerService := NewFileManagerService(fakeFileServiceClient, agentConfig, &sync.RWMutex{})
220227
fileManagerService.agentConfig.LibDir = manifestDirPath
221228
fileManagerService.manifestFilePath = manifestFilePath
229+
fileManagerService.configPath = filepath.Dir(tempFile.Name())
222230
err := fileManagerService.UpdateCurrentFilesOnDisk(ctx, filesOnDisk, false)
223231
require.NoError(t, err)
224232

@@ -236,7 +244,11 @@ func TestFileManagerService_ConfigApply_Delete(t *testing.T) {
236244
writeStatus, err := fileManagerService.ConfigApply(ctx, request)
237245
require.NoError(t, err)
238246
assert.NoFileExists(t, tempFile.Name())
239-
assert.Equal(t, fileManagerService.rollbackFileContents[tempFile.Name()], fileContent)
247+
248+
content, err := os.ReadFile(fileManagerService.tempRollbackDir + tempFile.Name())
249+
require.NoError(t, err)
250+
assert.Equal(t, fileContent, content)
251+
240252
assert.Equal(t,
241253
fileManagerService.fileActions[tempFile.Name()].File.GetFileMeta().GetName(),
242254
filesOnDisk[tempFile.Name()].GetFileMeta().GetName(),
@@ -278,6 +290,7 @@ func TestFileManagerService_ConfigApply_Failed(t *testing.T) {
278290

279291
fileManagerService := NewFileManagerService(fakeFileServiceClient, agentConfig, &sync.RWMutex{})
280292
fileManagerService.agentConfig.LibDir = manifestDirPath
293+
fileManagerService.configPath = filepath.Dir(filePath)
281294
fileManagerService.manifestFilePath = manifestFilePath
282295

283296
request := protos.CreateConfigApplyRequest(overview)
@@ -322,9 +335,18 @@ func TestFileManagerService_checkAllowedDirectory(t *testing.T) {
322335
require.Error(t, err)
323336
}
324337

338+
//nolint:usetesting // need to use MkDirTemp instead of t.tempDir for rollback as t.tempDir does not accept a pattern
325339
func TestFileManagerService_ClearCache(t *testing.T) {
340+
tempDir := t.TempDir()
341+
rollbackDir, err := os.MkdirTemp(tempDir, "rollback")
342+
require.NoError(t, err)
343+
configDir, err := os.MkdirTemp(tempDir, "config")
344+
require.NoError(t, err)
345+
326346
fakeFileServiceClient := &v1fakes.FakeFileServiceClient{}
327347
fileManagerService := NewFileManagerService(fakeFileServiceClient, types.AgentConfig(), &sync.RWMutex{})
348+
fileManagerService.tempConfigDir = configDir
349+
fileManagerService.tempRollbackDir = rollbackDir
328350

329351
filesCache := map[string]*model.FileCache{
330352
"file/path/test.conf": {
@@ -340,25 +362,27 @@ func TestFileManagerService_ClearCache(t *testing.T) {
340362
},
341363
}
342364

343-
contentsCache := map[string][]byte{
344-
"file/path/test.conf": []byte("some test data"),
345-
}
346-
347365
fileManagerService.fileActions = filesCache
348-
fileManagerService.rollbackFileContents = contentsCache
349366
assert.NotEmpty(t, fileManagerService.fileActions)
350-
assert.NotEmpty(t, fileManagerService.rollbackFileContents)
351367

352368
fileManagerService.ClearCache()
353369

354370
assert.Empty(t, fileManagerService.fileActions)
355-
assert.Empty(t, fileManagerService.rollbackFileContents)
371+
372+
_, statErr := os.Stat(fileManagerService.tempRollbackDir)
373+
assert.True(t, os.IsNotExist(statErr))
374+
_, statConfigErr := os.Stat(fileManagerService.tempConfigDir)
375+
assert.True(t, os.IsNotExist(statConfigErr))
356376
}
357377

378+
//nolint:usetesting // need to use MkDirTemp instead of t.tempDir for rollback as t.tempDir does not accept a pattern
358379
func TestFileManagerService_Rollback(t *testing.T) {
359380
ctx := context.Background()
360381
tempDir := t.TempDir()
361382

383+
rollbackDir, mkdirErr := os.MkdirTemp(tempDir, "rollback")
384+
require.NoError(t, mkdirErr)
385+
362386
deleteFilePath := filepath.Join(tempDir, "nginx_delete.conf")
363387

364388
newFileContent := []byte("location /test {\n return 200 \"This config needs to be rolled back\\n\";\n}")
@@ -373,6 +397,25 @@ func TestFileManagerService_Rollback(t *testing.T) {
373397
_, writeErr = updateFile.Write(newFileContent)
374398
require.NoError(t, writeErr)
375399

400+
helpers.CreateDirWithErrorCheck(t, rollbackDir+tempDir)
401+
402+
tempAddFile, createErr := os.Create(rollbackDir + addFile.Name())
403+
require.NoError(t, createErr)
404+
_, writeErr = tempAddFile.Write(oldFileContent)
405+
require.NoError(t, writeErr)
406+
407+
tempUpdateFile, createErr := os.Create(rollbackDir + updateFile.Name())
408+
require.NoError(t, createErr)
409+
_, writeErr = tempUpdateFile.Write(oldFileContent)
410+
require.NoError(t, writeErr)
411+
t.Log(tempUpdateFile.Name())
412+
413+
tempDeleteFile, createErr := os.Create(rollbackDir + tempDir + "/nginx_delete.conf")
414+
require.NoError(t, createErr)
415+
_, writeErr = tempDeleteFile.Write(oldFileContent)
416+
require.NoError(t, writeErr)
417+
t.Log(tempDeleteFile.Name())
418+
376419
manifestDirPath := tempDir
377420
manifestFilePath := manifestDirPath + "/manifest.json"
378421
helpers.CreateFileWithErrorCheck(t, manifestDirPath, "manifest.json")
@@ -430,17 +473,14 @@ func TestFileManagerService_Rollback(t *testing.T) {
430473
},
431474
},
432475
}
433-
fileContentCache := map[string][]byte{
434-
deleteFilePath: oldFileContent,
435-
updateFile.Name(): oldFileContent,
436-
}
437476

438477
instanceID := protos.NginxOssInstance([]string{}).GetInstanceMeta().GetInstanceId()
439478
fakeFileServiceClient := &v1fakes.FakeFileServiceClient{}
440479
fileManagerService := NewFileManagerService(fakeFileServiceClient, types.AgentConfig(), &sync.RWMutex{})
441-
fileManagerService.rollbackFileContents = fileContentCache
442480
fileManagerService.fileActions = filesCache
443481
fileManagerService.agentConfig.LibDir = manifestDirPath
482+
fileManagerService.tempRollbackDir = rollbackDir
483+
fileManagerService.configPath = filepath.Dir(updateFile.Name())
444484
fileManagerService.manifestFilePath = manifestFilePath
445485

446486
err := fileManagerService.Rollback(ctx, instanceID)
@@ -622,6 +662,7 @@ func TestFileManagerService_DetermineFileActions(t *testing.T) {
622662
fileManagerService := NewFileManagerService(fakeFileServiceClient, types.AgentConfig(), &sync.RWMutex{})
623663
fileManagerService.agentConfig.LibDir = manifestDirPath
624664
fileManagerService.manifestFilePath = manifestFilePath
665+
fileManagerService.configPath = filepath.Dir(updateTestFile.Name())
625666

626667
require.NoError(tt, err)
627668

@@ -1013,20 +1054,22 @@ func TestFileManagerService_deleteTempFiles(t *testing.T) {
10131054

10141055
func TestFileManagerService_createTempConfigDirectory(t *testing.T) {
10151056
agentConfig := types.AgentConfig()
1016-
agentConfig.LibDir = t.TempDir()
1057+
tempDir := t.TempDir()
1058+
configPath := tempDir
10171059

10181060
fileManagerService := FileManagerService{
10191061
agentConfig: agentConfig,
1062+
configPath: configPath,
10201063
}
10211064

1022-
dir, err := fileManagerService.createTempConfigDirectory(t.Context(), "config")
1065+
dir, err := fileManagerService.createTempConfigDirectory("config")
10231066
assert.NotEmpty(t, dir)
10241067
require.NoError(t, err)
10251068

10261069
// Test for unknown directory path
1027-
agentConfig.LibDir = "/unknown/"
1070+
fileManagerService.configPath = "/unknown/"
10281071

1029-
dir, err = fileManagerService.createTempConfigDirectory(t.Context(), "config")
1072+
dir, err = fileManagerService.createTempConfigDirectory("config")
10301073
assert.Empty(t, dir)
10311074
require.Error(t, err)
10321075
}

internal/file/file_operator_test.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,6 @@ func TestFileOperator_MoveFile_fileExists(t *testing.T) {
6868
err = fileOperator.MoveFile(t.Context(), tempFile, newFile)
6969
require.NoError(t, err)
7070

71-
assert.NoFileExists(t, tempFile)
7271
assert.FileExists(t, newFile)
7372
}
7473

internal/file/file_plugin.go

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,6 @@ func (fp *FilePlugin) CleanUpConfigApply(ctx context.Context,
144144
) {
145145
fp.fileManagerService.ClearCache()
146146

147-
slog.InfoContext(ctx, "Cleaned up temp files")
148147
enableWatcher := &model.EnableWatchers{
149148
ConfigContext: configContext,
150149
InstanceID: instanceID,
@@ -188,7 +187,7 @@ func (fp *FilePlugin) handleConfigApplyComplete(ctx context.Context, msg *bus.Me
188187
}
189188

190189
func (fp *FilePlugin) handleReloadSuccess(ctx context.Context, msg *bus.Message) {
191-
slog.InfoContext(ctx, "File plugin received reload success message", "data", msg.Data)
190+
slog.DebugContext(ctx, "File plugin received reload success message", "data", msg.Data)
192191

193192
successMessage, ok := msg.Data.(*model.ReloadSuccess)
194193

@@ -210,7 +209,6 @@ func (fp *FilePlugin) handleReloadSuccess(ctx context.Context, msg *bus.Message)
210209
slog.ErrorContext(ctx, "Unable to update current files on disk", "error", updateError)
211210
}
212211
}
213-
214212
fp.messagePipe.Process(ctx, &bus.Message{Topic: bus.DataPlaneResponseTopic, Data: successMessage.DataPlaneResponse})
215213
}
216214

internal/watcher/credentials/credential_watcher_service.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ func (cws *CredentialWatcherService) handleEvent(ctx context.Context, event fsno
146146
return
147147
}
148148

149-
slog.InfoContext(ctx, "Credential Processing FSNotify event", "event", event)
149+
slog.DebugContext(ctx, "Processing FSNotify event", "event", event)
150150

151151
switch {
152152
case event.Has(fsnotify.Remove):

internal/watcher/file/file_watcher_service.go

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,6 @@ func (fws *FileWatcherService) Watch(ctx context.Context, ch chan<- FileUpdateMe
8989
if fws.watcher != nil {
9090
select {
9191
case event := <-fws.watcher.Events:
92-
slog.InfoContext(ctx, "--------- Event received", "event", event)
9392
fws.handleEvent(ctx, event)
9493
case watcherError := <-fws.watcher.Errors:
9594
slog.ErrorContext(ctx, "Unexpected error in file watcher", "error", watcherError)
@@ -98,8 +97,25 @@ func (fws *FileWatcherService) Watch(ctx context.Context, ch chan<- FileUpdateMe
9897
}
9998
}
10099

101-
func (fws *FileWatcherService) SetEnabled(enabled bool) {
102-
fws.enabled.Store(enabled)
100+
func (fws *FileWatcherService) DisableWatcher(ctx context.Context) {
101+
if fws.watcher != nil && fws.watcher.WatchList() != nil {
102+
paths := fws.watcher.WatchList()
103+
slog.DebugContext(ctx, "Removing watchers", "paths", paths)
104+
for _, filePath := range paths {
105+
err := fws.watcher.Remove(filePath)
106+
if err != nil {
107+
slog.ErrorContext(ctx, "Unable to remove watcher file", "path", filePath, "error", err)
108+
}
109+
}
110+
}
111+
fws.enabled.Store(false)
112+
}
113+
114+
func (fws *FileWatcherService) EnableWatcher(ctx context.Context) {
115+
if fws.watcher != nil && fws.watcher.WatchList() != nil && len(fws.watcher.WatchList()) == 0 {
116+
fws.addWatchers(ctx)
117+
}
118+
fws.enabled.Store(true)
103119
}
104120

105121
func (fws *FileWatcherService) Update(ctx context.Context, nginxConfigContext *model.NginxConfigContext) {
@@ -173,16 +189,13 @@ func (fws *FileWatcherService) removeWatchers(ctx context.Context) {
173189
}
174190

175191
func (fws *FileWatcherService) handleEvent(ctx context.Context, event fsnotify.Event) {
176-
slog.InfoContext(ctx, "Is enabled", "bool", fws.enabled.Load())
177192
if fws.enabled.Load() {
178193
if fws.isEventSkippable(event) {
179194
return
180195
}
181196

182-
slog.InfoContext(ctx, "Processing FSNotify event", "event", event)
197+
slog.DebugContext(ctx, "Processing FSNotify event", "event", event)
183198
fws.filesChanged.Store(true)
184-
} else {
185-
slog.InfoContext(ctx, "Ignoring FSNotify event", "event", event)
186199
}
187200
}
188201

0 commit comments

Comments
 (0)