Skip to content

Commit 944c71d

Browse files
authored
Ensure only files are in file overview in config apply request (#1395)
1 parent 6970629 commit 944c71d

File tree

2 files changed

+73
-13
lines changed

2 files changed

+73
-13
lines changed

internal/file/file_manager_service.go

Lines changed: 44 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,8 @@ func (fms *FileManagerService) ConfigApply(ctx context.Context,
176176

177177
fms.fileActions = diffFiles
178178

179+
slog.DebugContext(ctx, "Executing config apply file actions", "actions", diffFiles)
180+
179181
rollbackTempFilesErr := fms.backupFiles(ctx)
180182
if rollbackTempFilesErr != nil {
181183
return model.Error, rollbackTempFilesErr
@@ -373,24 +375,58 @@ func (fms *FileManagerService) DetermineFileActions(
373375
for _, modifiedFile := range modifiedFiles {
374376
fileName := modifiedFile.File.GetFileMeta().GetName()
375377
currentFile, ok := filesMap[fileName]
376-
// default to unchanged action
377378
modifiedFile.Action = model.Unchanged
378379

379-
// if file is unmanaged, action is set to unchanged so file is skipped when performing actions
380+
// If file is unmanaged, action is set to unchanged so file is skipped when performing actions.
380381
if modifiedFile.File.GetUnmanaged() {
381382
slog.DebugContext(ctx, "Skipping unmanaged file updates", "file_name", fileName)
382383
continue
383384
}
384-
// if file doesn't exist in the current files, file has been added
385-
// set file action
386-
if _, statErr := os.Stat(fileName); errors.Is(statErr, os.ErrNotExist) {
385+
386+
// If file currently exists on disk, is being tracked in manifest and file hash is different.
387+
// Treat it as a file update.
388+
if ok && modifiedFile.File.GetFileMeta().GetHash() != currentFile.GetFileMeta().GetHash() {
389+
slog.DebugContext(ctx, "Tracked file requires updating", "file_name", fileName)
390+
modifiedFile.Action = model.Update
391+
fileDiff[fileName] = modifiedFile
392+
393+
continue
394+
}
395+
396+
fileStats, statErr := os.Stat(fileName)
397+
398+
// If file doesn't exist on disk.
399+
// Treat it as adding a new file.
400+
if errors.Is(statErr, os.ErrNotExist) {
401+
slog.DebugContext(ctx, "New untracked file needs to be created", "file_name", fileName)
387402
modifiedFile.Action = model.Add
388403
fileDiff[fileName] = modifiedFile
389404

390405
continue
391-
// if file currently exists and file hash is different, file has been updated
392-
// copy contents, set file action
393-
} else if ok && modifiedFile.File.GetFileMeta().GetHash() != currentFile.GetFileMeta().GetHash() {
406+
}
407+
408+
// If there is an error other than not existing, return that error.
409+
if statErr != nil {
410+
return nil, fmt.Errorf("unable to stat file %s: %w", fileName, statErr)
411+
}
412+
413+
// If there is a directory with the same name, return an error.
414+
if fileStats.IsDir() {
415+
return nil, fmt.Errorf(
416+
"unable to create file %s since a directory with the same name already exists",
417+
fileName,
418+
)
419+
}
420+
421+
// If file already exists on disk but is not being tracked in manifest and the file hash is different.
422+
// Treat it as a file update.
423+
metadataOfFileOnDisk, err := files.FileMeta(fileName)
424+
if err != nil {
425+
return nil, fmt.Errorf("unable to get file metadata for %s: %w", fileName, err)
426+
}
427+
428+
if metadataOfFileOnDisk.GetHash() != modifiedFile.File.GetFileMeta().GetHash() {
429+
slog.DebugContext(ctx, "Untracked file requires updating", "file_name", fileName)
394430
modifiedFile.Action = model.Update
395431
fileDiff[fileName] = modifiedFile
396432
}

internal/file/file_manager_service_test.go

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -763,12 +763,12 @@ func TestFileManagerService_DetermineFileActions(t *testing.T) {
763763
modifiedFiles: map[string]*model.FileCache{
764764
addTestFile.Name(): {
765765
File: &mpi.File{
766-
FileMeta: protos.FileMeta(addTestFile.Name(), files.GenerateHash(fileContent)),
766+
FileMeta: protos.FileMeta(addTestFile.Name(), files.GenerateHash(addFileContent)),
767767
},
768768
},
769769
updateTestFile.Name(): {
770770
File: &mpi.File{
771-
FileMeta: protos.FileMeta(updateTestFile.Name(), files.GenerateHash(fileContent)),
771+
FileMeta: protos.FileMeta(updateTestFile.Name(), files.GenerateHash(updatedFileContent)),
772772
},
773773
},
774774
deleteTestFile.Name(): {
@@ -782,10 +782,10 @@ func TestFileManagerService_DetermineFileActions(t *testing.T) {
782782
FileMeta: protos.FileMeta(deleteTestFile.Name(), files.GenerateHash(fileContent)),
783783
},
784784
updateTestFile.Name(): {
785-
FileMeta: protos.FileMeta(updateTestFile.Name(), files.GenerateHash(fileContent)),
785+
FileMeta: protos.FileMeta(updateTestFile.Name(), files.GenerateHash(updatedFileContent)),
786786
},
787787
addTestFile.Name(): {
788-
FileMeta: protos.FileMeta(addTestFile.Name(), files.GenerateHash(fileContent)),
788+
FileMeta: protos.FileMeta(addTestFile.Name(), files.GenerateHash(addFileContent)),
789789
},
790790
},
791791
expectedCache: make(map[string]*model.FileCache),
@@ -805,6 +805,24 @@ func TestFileManagerService_DetermineFileActions(t *testing.T) {
805805
expectedContent: make(map[string][]byte),
806806
expectedError: nil,
807807
},
808+
{
809+
name: "Test 4: File is actually a directory",
810+
allowedDirs: []string{tempDir},
811+
modifiedFiles: map[string]*model.FileCache{
812+
tempDir: {
813+
File: &mpi.File{
814+
FileMeta: protos.FileMeta(tempDir, files.GenerateHash(fileContent)),
815+
},
816+
},
817+
},
818+
currentFiles: make(map[string]*mpi.File),
819+
expectedCache: map[string]*model.FileCache(nil),
820+
expectedContent: make(map[string][]byte),
821+
expectedError: fmt.Errorf(
822+
"unable to create file %s since a directory with the same name already exists",
823+
tempDir,
824+
),
825+
},
808826
}
809827

810828
for _, test := range tests {
@@ -828,7 +846,13 @@ func TestFileManagerService_DetermineFileActions(t *testing.T) {
828846
test.currentFiles,
829847
test.modifiedFiles,
830848
)
831-
require.NoError(tt, fileActionErr)
849+
850+
if test.expectedError != nil {
851+
require.EqualError(tt, fileActionErr, test.expectedError.Error())
852+
} else {
853+
require.NoError(tt, fileActionErr)
854+
}
855+
832856
assert.Equal(tt, test.expectedCache, diff)
833857
})
834858
}

0 commit comments

Comments
 (0)