diff --git a/internal/datasource/config/nginx_config_parser.go b/internal/datasource/config/nginx_config_parser.go index 541530b48..272d924b0 100644 --- a/internal/datasource/config/nginx_config_parser.go +++ b/internal/datasource/config/nginx_config_parser.go @@ -44,6 +44,29 @@ const ( locationDirective = "location" ) +var globFunction = func(path string) ([]string, error) { + matches, err := filepath.Glob(path) + if err != nil { + return nil, err + } + + // Exclude hidden files unless the glob pattern itself starts with a dot + if !strings.HasPrefix(filepath.Base(path), ".") { + filteredMatches := make([]string, 0) + + for _, match := range matches { + base := filepath.Base(match) + if !strings.HasPrefix(base, ".") { + filteredMatches = append(filteredMatches, match) + } + } + + return filteredMatches, nil + } + + return matches, nil +} + //go:generate go run github.com/maxbrunsfeld/counterfeiter/v6@v6.8.1 -generate //counterfeiter:generate . ConfigParser @@ -95,6 +118,7 @@ func (ncp *NginxConfigParser) Parse(ctx context.Context, instance *mpi.Instance) LexOptions: crossplane.LexOptions{ Lexers: []crossplane.RegisterLexer{lua.RegisterLexer()}, }, + Glob: globFunction, }, ) if err != nil { diff --git a/internal/file/file_manager_service.go b/internal/file/file_manager_service.go index b358a11c6..6c7ed4afb 100644 --- a/internal/file/file_manager_service.go +++ b/internal/file/file_manager_service.go @@ -13,7 +13,6 @@ import ( "fmt" "log/slog" "os" - "path" "path/filepath" "strconv" "sync" @@ -82,7 +81,6 @@ type ( err error) Rollback(ctx context.Context, instanceID string) error ClearCache() - SetConfigPath(configPath string) ConfigUpload(ctx context.Context, configUploadRequest *mpi.ConfigUploadRequest) error ConfigUpdate(ctx context.Context, nginxConfigContext *model.NginxConfigContext) UpdateCurrentFilesOnDisk(ctx context.Context, updateFiles map[string]*mpi.File, referenced bool) error @@ -108,9 +106,6 @@ type FileManagerService struct { currentFilesOnDisk map[string]*mpi.File // key is file path previousManifestFiles map[string]*model.ManifestFile manifestFilePath string - tempConfigDir string - tempRollbackDir string - tempConfigPath string rollbackManifest bool filesMutex sync.RWMutex } @@ -131,11 +126,6 @@ func NewFileManagerService(fileServiceClient mpi.FileServiceClient, agentConfig } } -func (fms *FileManagerService) SetConfigPath(configPath string) { - fms.tempConfigPath = fmt.Sprintf("%s/.agent-%s", filepath.Dir(configPath), fms.agentConfig.UUID) - fms.ClearCache() -} - func (fms *FileManagerService) ResetClient(ctx context.Context, fileServiceClient mpi.FileServiceClient) { fms.fileServiceOperator.UpdateClient(ctx, fileServiceClient) slog.DebugContext(ctx, "File manager service reset client successfully") @@ -152,9 +142,6 @@ func (fms *FileManagerService) SetIsConnected(isConnected bool) { func (fms *FileManagerService) ConfigApply(ctx context.Context, configApplyRequest *mpi.ConfigApplyRequest, ) (status model.WriteStatus, err error) { - var configTempErr error - var rollbackTempErr error - fms.rollbackManifest = true fileOverview := configApplyRequest.GetOverview() @@ -189,16 +176,6 @@ func (fms *FileManagerService) ConfigApply(ctx context.Context, fms.fileActions = diffFiles - fms.tempConfigDir, configTempErr = fms.createTempConfigDirectory("config") - if configTempErr != nil { - return model.Error, configTempErr - } - - fms.tempRollbackDir, rollbackTempErr = fms.createTempConfigDirectory("rollback") - if rollbackTempErr != nil { - return model.Error, rollbackTempErr - } - rollbackTempFilesErr := fms.backupFiles(ctx) if rollbackTempFilesErr != nil { return model.Error, rollbackTempFilesErr @@ -220,14 +197,22 @@ func (fms *FileManagerService) ConfigApply(ctx context.Context, } func (fms *FileManagerService) ClearCache() { - slog.Debug("Clearing cache and temp files") - clear(fms.fileActions) - clear(fms.previousManifestFiles) + slog.Debug("Clearing cache and backup files") - configErr := os.RemoveAll(fms.tempConfigPath) - if configErr != nil && !os.IsNotExist(configErr) { - slog.Error("Error removing temp directory", "path", fms.tempConfigDir, "err", configErr) + for _, fileAction := range fms.fileActions { + if fileAction.Action == model.Update || fileAction.Action == model.Delete { + tempFilePath := tempBackupFilePath(fileAction.File.GetFileMeta().GetName()) + if err := os.Remove(tempFilePath); err != nil && !os.IsNotExist(err) { + slog.Warn("Unable to delete backup file", + "file", fileAction.File.GetFileMeta().GetName(), + "error", err, + ) + } + } } + + clear(fms.fileActions) + clear(fms.previousManifestFiles) } //nolint:revive,cyclop // cognitive-complexity of 13 max is 12, loop is needed cant be broken up @@ -502,7 +487,7 @@ func (fms *FileManagerService) backupFiles(ctx context.Context) error { continue } - tempFilePath := filepath.Join(fms.tempRollbackDir, filePath) + tempFilePath := tempBackupFilePath(filePath) slog.DebugContext(ctx, "Attempting to backup file content since file exists", "temp_path", tempFilePath) moveErr := fms.fileOperator.MoveFile(ctx, filePath, tempFilePath) @@ -519,7 +504,7 @@ func (fms *FileManagerService) restoreFiles(fileAction *model.FileCache) ([]byte fileMeta := fileAction.File.GetFileMeta() fileName := fileMeta.GetName() - tempFilePath := filepath.Join(fms.tempRollbackDir, fileName) + tempFilePath := tempBackupFilePath(fileName) // Create parent directories for the target file if they don't exist if err := os.MkdirAll(filepath.Dir(fileName), dirPerm); err != nil { @@ -570,26 +555,24 @@ func (fms *FileManagerService) manifestFile() (map[string]*model.ManifestFile, m func (fms *FileManagerService) executeFileActions(ctx context.Context) (actionError error) { // Download files to temporary location - downloadError := fms.downloadUpdatedFilesToTempLocation(ctx, fms.tempConfigDir) + downloadError := fms.downloadUpdatedFilesToTempLocation(ctx) if downloadError != nil { return downloadError } // Remove temp files if there is a failure moving or deleting files - actionError = fms.moveOrDeleteFiles(ctx, fms.tempConfigDir, actionError) + actionError = fms.moveOrDeleteFiles(ctx, actionError) if actionError != nil { - fms.deleteTempFiles(ctx, fms.tempConfigDir) + fms.deleteTempFiles(ctx) } return actionError } -func (fms *FileManagerService) downloadUpdatedFilesToTempLocation( - ctx context.Context, tempDir string, -) (updateError error) { +func (fms *FileManagerService) downloadUpdatedFilesToTempLocation(ctx context.Context) (updateError error) { for _, fileAction := range fms.fileActions { if fileAction.Action == model.Add || fileAction.Action == model.Update { - tempFilePath := filepath.Join(tempDir, fileAction.File.GetFileMeta().GetName()) + tempFilePath := tempFilePath(fileAction.File.GetFileMeta().GetName()) slog.DebugContext( ctx, @@ -608,7 +591,7 @@ func (fms *FileManagerService) downloadUpdatedFilesToTempLocation( return updateError } -func (fms *FileManagerService) moveOrDeleteFiles(ctx context.Context, tempDir string, actionError error) error { +func (fms *FileManagerService) moveOrDeleteFiles(ctx context.Context, actionError error) error { actionsLoop: for _, fileAction := range fms.fileActions { switch fileAction.Action { @@ -624,7 +607,8 @@ actionsLoop: continue case model.Add, model.Update: fileMeta := fileAction.File.GetFileMeta() - err := fms.fileServiceOperator.RenameFile(ctx, fileMeta.GetHash(), fileMeta.GetName(), tempDir) + tempFilePath := tempFilePath(fileAction.File.GetFileMeta().GetName()) + err := fms.fileServiceOperator.RenameFile(ctx, fileMeta.GetHash(), tempFilePath, fileMeta.GetName()) if err != nil { actionError = err @@ -638,11 +622,11 @@ actionsLoop: return actionError } -func (fms *FileManagerService) deleteTempFiles(ctx context.Context, tempDir string) { +func (fms *FileManagerService) deleteTempFiles(ctx context.Context) { for _, fileAction := range fms.fileActions { if fileAction.Action == model.Add || fileAction.Action == model.Update { - tempFile := path.Join(tempDir, fileAction.File.GetFileMeta().GetName()) - if err := os.Remove(tempFile); err != nil && !os.IsNotExist(err) { + tempFilePath := tempFilePath(fileAction.File.GetFileMeta().GetName()) + if err := os.Remove(tempFilePath); err != nil && !os.IsNotExist(err) { slog.ErrorContext( ctx, "Error deleting temp file", "file", fileAction.File.GetFileMeta().GetName(), @@ -767,21 +751,6 @@ func (fms *FileManagerService) convertToFile(manifestFile *model.ManifestFile) * } } -func (fms *FileManagerService) createTempConfigDirectory(pattern string) (string, error) { - if _, err := os.Stat(fms.tempConfigPath); os.IsNotExist(err) { - mkdirErr := os.MkdirAll(fms.tempConfigPath, dirPerm) - if mkdirErr != nil { - return "", mkdirErr - } - } - tempDir, tempDirError := os.MkdirTemp(fms.tempConfigPath, pattern) - if tempDirError != nil { - return "", fmt.Errorf("failed creating temp config directory: %w", tempDirError) - } - - return tempDir, nil -} - // ConvertToMapOfFiles converts a list of files to a map of file caches (file and action) with the file name as the key func ConvertToMapOfFileCache(convertFiles []*mpi.File) map[string]*model.FileCache { filesMap := make(map[string]*model.FileCache) @@ -793,3 +762,13 @@ func ConvertToMapOfFileCache(convertFiles []*mpi.File) map[string]*model.FileCac return filesMap } + +func tempFilePath(fileName string) string { + tempFileName := "." + filepath.Base(fileName) + ".agent.tmp" + return filepath.Join(filepath.Dir(fileName), tempFileName) +} + +func tempBackupFilePath(fileName string) string { + tempFileName := "." + filepath.Base(fileName) + ".agent.backup" + return filepath.Join(filepath.Dir(fileName), tempFileName) +} diff --git a/internal/file/file_manager_service_test.go b/internal/file/file_manager_service_test.go index 0006beda2..e42128063 100644 --- a/internal/file/file_manager_service_test.go +++ b/internal/file/file_manager_service_test.go @@ -11,7 +11,6 @@ import ( "errors" "fmt" "os" - "path" "path/filepath" "sync" "testing" @@ -59,7 +58,6 @@ func TestFileManagerService_ConfigApply_Add(t *testing.T) { agentConfig.AllowedDirectories = []string{tempDir} fileManagerService := NewFileManagerService(fakeFileServiceClient, agentConfig, &sync.RWMutex{}) - fileManagerService.tempConfigPath = filepath.Dir(filePath) fileManagerService.agentConfig.LibDir = manifestDirPath fileManagerService.manifestFilePath = manifestFilePath @@ -109,7 +107,6 @@ func TestFileManagerService_ConfigApply_Add_LargeFile(t *testing.T) { agentConfig.AllowedDirectories = []string{tempDir} fileManagerService := NewFileManagerService(fakeFileServiceClient, agentConfig, &sync.RWMutex{}) fileManagerService.agentConfig.LibDir = manifestDirPath - fileManagerService.tempConfigPath = filepath.Dir(filePath) fileManagerService.manifestFilePath = manifestFilePath request := protos.CreateConfigApplyRequest(overview) @@ -170,7 +167,6 @@ func TestFileManagerService_ConfigApply_Update(t *testing.T) { fileManagerService := NewFileManagerService(fakeFileServiceClient, agentConfig, &sync.RWMutex{}) fileManagerService.agentConfig.LibDir = manifestDirPath - fileManagerService.tempConfigPath = filepath.Dir(tempFile.Name()) fileManagerService.manifestFilePath = manifestFilePath err := fileManagerService.UpdateCurrentFilesOnDisk(ctx, filesOnDisk, false) require.NoError(t, err) @@ -183,7 +179,7 @@ func TestFileManagerService_ConfigApply_Update(t *testing.T) { require.NoError(t, readErr) assert.Equal(t, fileContent, data) - content, err := os.ReadFile(fileManagerService.tempRollbackDir + tempFile.Name()) + content, err := os.ReadFile(tempBackupFilePath(tempFile.Name())) require.NoError(t, err) assert.Equal(t, previousFileContent, content) @@ -226,7 +222,6 @@ func TestFileManagerService_ConfigApply_Delete(t *testing.T) { fileManagerService := NewFileManagerService(fakeFileServiceClient, agentConfig, &sync.RWMutex{}) fileManagerService.agentConfig.LibDir = manifestDirPath fileManagerService.manifestFilePath = manifestFilePath - fileManagerService.tempConfigPath = filepath.Dir(tempFile.Name()) err := fileManagerService.UpdateCurrentFilesOnDisk(ctx, filesOnDisk, false) require.NoError(t, err) @@ -245,7 +240,7 @@ func TestFileManagerService_ConfigApply_Delete(t *testing.T) { require.NoError(t, err) assert.NoFileExists(t, tempFile.Name()) - content, err := os.ReadFile(fileManagerService.tempRollbackDir + tempFile.Name()) + content, err := os.ReadFile(tempBackupFilePath(tempFile.Name())) require.NoError(t, err) assert.Equal(t, fileContent, content) @@ -290,7 +285,6 @@ func TestFileManagerService_ConfigApply_Failed(t *testing.T) { fileManagerService := NewFileManagerService(fakeFileServiceClient, agentConfig, &sync.RWMutex{}) fileManagerService.agentConfig.LibDir = manifestDirPath - fileManagerService.tempConfigPath = filepath.Dir(filePath) fileManagerService.manifestFilePath = manifestFilePath request := protos.CreateConfigApplyRequest(overview) @@ -332,7 +326,6 @@ func TestFileManagerService_ConfigApply_FileWithExecutePermissions(t *testing.T) agentConfig.AllowedDirectories = []string{tempDir} fileManagerService := NewFileManagerService(fakeFileServiceClient, agentConfig, &sync.RWMutex{}) - fileManagerService.tempConfigPath = filepath.Dir(filePath) fileManagerService.agentConfig.LibDir = manifestDirPath fileManagerService.manifestFilePath = manifestFilePath @@ -516,16 +509,9 @@ func TestFileManagerService_ClearCache(t *testing.T) { tempPath := fmt.Sprintf("%s.agent_%s", tempDir, agentConfig.UUID) err := os.Mkdir(tempPath, dirPerm) require.NoError(t, err) - rollbackDir, err := os.MkdirTemp(tempPath, "rollback") - require.NoError(t, err) - configDir, err := os.MkdirTemp(tempPath, "config") - require.NoError(t, err) fakeFileServiceClient := &v1fakes.FakeFileServiceClient{} fileManagerService := NewFileManagerService(fakeFileServiceClient, agentConfig, &sync.RWMutex{}) - fileManagerService.tempConfigDir = configDir - fileManagerService.tempRollbackDir = rollbackDir - fileManagerService.tempConfigPath = tempPath filesCache := map[string]*model.FileCache{ "file/path/test.conf": { @@ -547,11 +533,6 @@ func TestFileManagerService_ClearCache(t *testing.T) { fileManagerService.ClearCache() assert.Empty(t, fileManagerService.fileActions) - - _, statErr := os.Stat(fileManagerService.tempRollbackDir) - assert.True(t, os.IsNotExist(statErr)) - _, statConfigErr := os.Stat(fileManagerService.tempConfigDir) - assert.True(t, os.IsNotExist(statConfigErr)) } //nolint:usetesting // need to use MkDirTemp instead of t.tempDir for rollback as t.tempDir does not accept a pattern @@ -559,9 +540,6 @@ func TestFileManagerService_Rollback(t *testing.T) { ctx := context.Background() tempDir := t.TempDir() - rollbackDir, mkdirErr := os.MkdirTemp(tempDir, "rollback") - require.NoError(t, mkdirErr) - deleteFilePath := filepath.Join(tempDir, "nginx_delete.conf") newFileContent := []byte("location /test {\n return 200 \"This config needs to be rolled back\\n\";\n}") @@ -576,20 +554,18 @@ func TestFileManagerService_Rollback(t *testing.T) { _, writeErr = updateFile.Write(newFileContent) require.NoError(t, writeErr) - helpers.CreateDirWithErrorCheck(t, rollbackDir+tempDir) - - tempAddFile, createErr := os.Create(rollbackDir + addFile.Name()) + tempAddFile, createErr := os.Create(tempBackupFilePath(addFile.Name())) require.NoError(t, createErr) _, writeErr = tempAddFile.Write(oldFileContent) require.NoError(t, writeErr) - tempUpdateFile, createErr := os.Create(rollbackDir + updateFile.Name()) + tempUpdateFile, createErr := os.Create(tempBackupFilePath(updateFile.Name())) require.NoError(t, createErr) _, writeErr = tempUpdateFile.Write(oldFileContent) require.NoError(t, writeErr) t.Log(tempUpdateFile.Name()) - tempDeleteFile, createErr := os.Create(rollbackDir + tempDir + "/nginx_delete.conf") + tempDeleteFile, createErr := os.Create(tempBackupFilePath(tempDir + "/nginx_delete.conf")) require.NoError(t, createErr) _, writeErr = tempDeleteFile.Write(oldFileContent) require.NoError(t, writeErr) @@ -658,8 +634,6 @@ func TestFileManagerService_Rollback(t *testing.T) { fileManagerService := NewFileManagerService(fakeFileServiceClient, types.AgentConfig(), &sync.RWMutex{}) fileManagerService.fileActions = filesCache fileManagerService.agentConfig.LibDir = manifestDirPath - fileManagerService.tempRollbackDir = rollbackDir - fileManagerService.tempConfigPath = filepath.Dir(updateFile.Name()) fileManagerService.manifestFilePath = manifestFilePath err := fileManagerService.Rollback(ctx, instanceID) @@ -846,7 +820,6 @@ func TestFileManagerService_DetermineFileActions(t *testing.T) { fileManagerService.agentConfig.AllowedDirectories = test.allowedDirs fileManagerService.agentConfig.LibDir = manifestDirPath fileManagerService.manifestFilePath = manifestFilePath - fileManagerService.tempConfigPath = filepath.Dir(updateTestFile.Name()) require.NoError(tt, err) @@ -1200,61 +1173,3 @@ rQHX6DP4w6IwZY8JB8LS }) } } - -func TestFileManagerService_deleteTempFiles(t *testing.T) { - tempDir := t.TempDir() - tempFile := path.Join(tempDir, "/etc/nginx/nginx.conf") - - err := os.MkdirAll(path.Dir(tempFile), 0o755) - require.NoError(t, err) - - _, err = os.Create(tempFile) - require.NoError(t, err) - - fileManagerService := FileManagerService{ - fileActions: map[string]*model.FileCache{ - "/etc/nginx/nginx.conf": { - File: &mpi.File{ - FileMeta: &mpi.FileMeta{ - Name: "/etc/nginx/nginx.conf", - }, - }, - Action: model.Update, - }, - "/etc/nginx/test.conf": { - File: &mpi.File{ - FileMeta: &mpi.FileMeta{ - Name: "/etc/nginx/test.conf", - }, - }, - Action: model.Add, - }, - }, - } - - fileManagerService.deleteTempFiles(t.Context(), tempDir) - - assert.NoFileExists(t, tempFile) -} - -func TestFileManagerService_createTempConfigDirectory(t *testing.T) { - agentConfig := types.AgentConfig() - tempDir := t.TempDir() - configPath := tempDir - - fileManagerService := FileManagerService{ - agentConfig: agentConfig, - tempConfigPath: configPath, - } - - dir, err := fileManagerService.createTempConfigDirectory("config") - assert.NotEmpty(t, dir) - require.NoError(t, err) - - // Test for unknown directory path - fileManagerService.tempConfigPath = "/unknown/" - - dir, err = fileManagerService.createTempConfigDirectory("config") - assert.Empty(t, dir) - require.Error(t, err) -} diff --git a/internal/file/file_plugin.go b/internal/file/file_plugin.go index 58c8b799f..a9747b7b3 100644 --- a/internal/file/file_plugin.go +++ b/internal/file/file_plugin.go @@ -367,7 +367,6 @@ func (fp *FilePlugin) handleNginxConfigUpdate(ctx context.Context, msg *bus.Mess return } - fp.fileManagerService.SetConfigPath(nginxConfigContext.ConfigPath) fp.fileManagerService.ConfigUpdate(ctx, nginxConfigContext) } diff --git a/internal/file/file_service_operator.go b/internal/file/file_service_operator.go index 9994af64c..19211c600 100644 --- a/internal/file/file_service_operator.go +++ b/internal/file/file_service_operator.go @@ -278,22 +278,21 @@ func (fso *FileServiceOperator) UpdateFile( // renameFile, renames (moves) file from tempDir to new location to update file. func (fso *FileServiceOperator) RenameFile( - ctx context.Context, hash, fileName, dir string, + ctx context.Context, hash, source, desination string, ) error { - slog.DebugContext(ctx, "Renaming file", "file", fileName) - tempFilePath := filepath.Join(dir, fileName) + slog.DebugContext(ctx, fmt.Sprintf("Renaming file %s to %s", source, desination)) // Create parent directories for the target file if they don't exist - if err := os.MkdirAll(filepath.Dir(fileName), dirPerm); err != nil { - return fmt.Errorf("failed to create directories for %s: %w", fileName, err) + if err := os.MkdirAll(filepath.Dir(desination), dirPerm); err != nil { + return fmt.Errorf("failed to create directories for %s: %w", desination, err) } - moveErr := os.Rename(tempFilePath, fileName) + moveErr := os.Rename(source, desination) if moveErr != nil { return fmt.Errorf("failed to rename file: %w", moveErr) } - return fso.validateFileHash(fileName, hash) + return fso.validateFileHash(desination, hash) } func (fso *FileServiceOperator) validateFileHash(filePath, expectedHash string) error { diff --git a/internal/file/filefakes/fake_file_manager_service_interface.go b/internal/file/filefakes/fake_file_manager_service_interface.go index 0a7a551ea..f2af670fe 100644 --- a/internal/file/filefakes/fake_file_manager_service_interface.go +++ b/internal/file/filefakes/fake_file_manager_service_interface.go @@ -89,11 +89,6 @@ type FakeFileManagerServiceInterface struct { rollbackReturnsOnCall map[int]struct { result1 error } - SetConfigPathStub func(string) - setConfigPathMutex sync.RWMutex - setConfigPathArgsForCall []struct { - arg1 string - } SetIsConnectedStub func(bool) setIsConnectedMutex sync.RWMutex setIsConnectedArgsForCall []struct { @@ -514,38 +509,6 @@ func (fake *FakeFileManagerServiceInterface) RollbackReturnsOnCall(i int, result }{result1} } -func (fake *FakeFileManagerServiceInterface) SetConfigPath(arg1 string) { - fake.setConfigPathMutex.Lock() - fake.setConfigPathArgsForCall = append(fake.setConfigPathArgsForCall, struct { - arg1 string - }{arg1}) - stub := fake.SetConfigPathStub - fake.recordInvocation("SetConfigPath", []interface{}{arg1}) - fake.setConfigPathMutex.Unlock() - if stub != nil { - fake.SetConfigPathStub(arg1) - } -} - -func (fake *FakeFileManagerServiceInterface) SetConfigPathCallCount() int { - fake.setConfigPathMutex.RLock() - defer fake.setConfigPathMutex.RUnlock() - return len(fake.setConfigPathArgsForCall) -} - -func (fake *FakeFileManagerServiceInterface) SetConfigPathCalls(stub func(string)) { - fake.setConfigPathMutex.Lock() - defer fake.setConfigPathMutex.Unlock() - fake.SetConfigPathStub = stub -} - -func (fake *FakeFileManagerServiceInterface) SetConfigPathArgsForCall(i int) string { - fake.setConfigPathMutex.RLock() - defer fake.setConfigPathMutex.RUnlock() - argsForCall := fake.setConfigPathArgsForCall[i] - return argsForCall.arg1 -} - func (fake *FakeFileManagerServiceInterface) SetIsConnected(arg1 bool) { fake.setIsConnectedMutex.Lock() fake.setIsConnectedArgsForCall = append(fake.setIsConnectedArgsForCall, struct { @@ -660,8 +623,6 @@ func (fake *FakeFileManagerServiceInterface) Invocations() map[string][][]interf defer fake.resetClientMutex.RUnlock() fake.rollbackMutex.RLock() defer fake.rollbackMutex.RUnlock() - fake.setConfigPathMutex.RLock() - defer fake.setConfigPathMutex.RUnlock() fake.setIsConnectedMutex.RLock() defer fake.setIsConnectedMutex.RUnlock() fake.updateCurrentFilesOnDiskMutex.RLock()