fix(stack/git): option to overwrite target path during dir move [EE-6871] (#11628)

pull/11652/head
Oscar Zhou 2024-04-22 10:34:32 +12:00 committed by GitHub
parent 0dd12a218b
commit 6623475035
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 31 additions and 9 deletions

View File

@ -934,7 +934,7 @@ func FileExists(filePath string) (bool, error) {
func (service *Service) SafeMoveDirectory(originalPath, newPath string) error { func (service *Service) SafeMoveDirectory(originalPath, newPath string) error {
// 1. Backup the source directory to a different folder // 1. Backup the source directory to a different folder
backupDir := fmt.Sprintf("%s-%s", filepath.Dir(originalPath), "backup") backupDir := fmt.Sprintf("%s-%s", filepath.Dir(originalPath), "backup")
err := MoveDirectory(originalPath, backupDir) err := MoveDirectory(originalPath, backupDir, false)
if err != nil { if err != nil {
return fmt.Errorf("failed to backup source directory: %w", err) return fmt.Errorf("failed to backup source directory: %w", err)
} }
@ -973,14 +973,14 @@ func restoreBackup(src, backupDir string) error {
return fmt.Errorf("failed to delete destination directory: %w", err) return fmt.Errorf("failed to delete destination directory: %w", err)
} }
err = MoveDirectory(backupDir, src) err = MoveDirectory(backupDir, src, false)
if err != nil { if err != nil {
return fmt.Errorf("failed to restore backup directory: %w", err) return fmt.Errorf("failed to restore backup directory: %w", err)
} }
return nil return nil
} }
func MoveDirectory(originalPath, newPath string) error { func MoveDirectory(originalPath, newPath string, overwriteTargetPath bool) error {
if _, err := os.Stat(originalPath); err != nil { if _, err := os.Stat(originalPath); err != nil {
return err return err
} }
@ -991,7 +991,13 @@ func MoveDirectory(originalPath, newPath string) error {
} }
if alreadyExists { if alreadyExists {
return errors.New("Target path already exists") if !overwriteTargetPath {
return fmt.Errorf("Target path already exists")
}
if err = os.RemoveAll(newPath); err != nil {
return fmt.Errorf("failed to overwrite path %s: %s", newPath, err.Error())
}
} }
return os.Rename(originalPath, newPath) return os.Rename(originalPath, newPath)

View File

@ -16,7 +16,7 @@ func Test_movePath_shouldFailIfSourceDirDoesNotExist(t *testing.T) {
file1 := addFile(destinationDir, "dir", "file") file1 := addFile(destinationDir, "dir", "file")
file2 := addFile(destinationDir, "file") file2 := addFile(destinationDir, "file")
err := MoveDirectory(sourceDir, destinationDir) err := MoveDirectory(sourceDir, destinationDir, false)
assert.Error(t, err, "move directory should fail when source path is missing") assert.Error(t, err, "move directory should fail when source path is missing")
assert.FileExists(t, file1, "destination dir contents should remain") assert.FileExists(t, file1, "destination dir contents should remain")
assert.FileExists(t, file2, "destination dir contents should remain") assert.FileExists(t, file2, "destination dir contents should remain")
@ -30,7 +30,7 @@ func Test_movePath_shouldFailIfDestinationDirExists(t *testing.T) {
file3 := addFile(destinationDir, "dir", "file") file3 := addFile(destinationDir, "dir", "file")
file4 := addFile(destinationDir, "file") file4 := addFile(destinationDir, "file")
err := MoveDirectory(sourceDir, destinationDir) err := MoveDirectory(sourceDir, destinationDir, false)
assert.Error(t, err, "move directory should fail when destination directory already exists") assert.Error(t, err, "move directory should fail when destination directory already exists")
assert.FileExists(t, file1, "source dir contents should remain") assert.FileExists(t, file1, "source dir contents should remain")
assert.FileExists(t, file2, "source dir contents should remain") assert.FileExists(t, file2, "source dir contents should remain")
@ -38,6 +38,22 @@ func Test_movePath_shouldFailIfDestinationDirExists(t *testing.T) {
assert.FileExists(t, file4, "destination dir contents should remain") assert.FileExists(t, file4, "destination dir contents should remain")
} }
func Test_movePath_succesIfOverwriteSetWhenDestinationDirExists(t *testing.T) {
sourceDir := t.TempDir()
file1 := addFile(sourceDir, "dir", "file")
file2 := addFile(sourceDir, "file")
destinationDir := t.TempDir()
file3 := addFile(destinationDir, "dir", "file")
file4 := addFile(destinationDir, "file")
err := MoveDirectory(sourceDir, destinationDir, true)
assert.NoError(t, err)
assert.NoFileExists(t, file1, "source dir contents should be moved")
assert.NoFileExists(t, file2, "source dir contents should be moved")
assert.FileExists(t, file3, "destination dir contents should remain")
assert.FileExists(t, file4, "destination dir contents should remain")
}
func Test_movePath_successWhenSourceExistsAndDestinationIsMissing(t *testing.T) { func Test_movePath_successWhenSourceExistsAndDestinationIsMissing(t *testing.T) {
tmp := t.TempDir() tmp := t.TempDir()
sourceDir := path.Join(tmp, "source") sourceDir := path.Join(tmp, "source")
@ -46,7 +62,7 @@ func Test_movePath_successWhenSourceExistsAndDestinationIsMissing(t *testing.T)
file2 := addFile(sourceDir, "file") file2 := addFile(sourceDir, "file")
destinationDir := path.Join(tmp, "destination") destinationDir := path.Join(tmp, "destination")
err := MoveDirectory(sourceDir, destinationDir) err := MoveDirectory(sourceDir, destinationDir, false)
assert.NoError(t, err) assert.NoError(t, err)
assert.NoFileExists(t, file1, "source dir contents should be moved") assert.NoFileExists(t, file1, "source dir contents should be moved")
assert.NoFileExists(t, file2, "source dir contents should be moved") assert.NoFileExists(t, file2, "source dir contents should be moved")

View File

@ -38,7 +38,7 @@ func CloneWithBackup(gitService portainer.GitService, fileService portainer.File
} }
} }
err = filesystem.MoveDirectory(options.ProjectPath, backupProjectPath) err = filesystem.MoveDirectory(options.ProjectPath, backupProjectPath, true)
if err != nil { if err != nil {
return cleanFn, errors.WithMessage(err, "Unable to move git repository directory") return cleanFn, errors.WithMessage(err, "Unable to move git repository directory")
} }
@ -48,7 +48,7 @@ func CloneWithBackup(gitService portainer.GitService, fileService portainer.File
err = gitService.CloneRepository(options.ProjectPath, options.URL, options.ReferenceName, options.Username, options.Password, options.TLSSkipVerify) err = gitService.CloneRepository(options.ProjectPath, options.URL, options.ReferenceName, options.Username, options.Password, options.TLSSkipVerify)
if err != nil { if err != nil {
cleanUp = false cleanUp = false
restoreError := filesystem.MoveDirectory(backupProjectPath, options.ProjectPath) restoreError := filesystem.MoveDirectory(backupProjectPath, options.ProjectPath, false)
if restoreError != nil { if restoreError != nil {
log.Warn().Err(restoreError).Msg("failed restoring backup folder") log.Warn().Err(restoreError).Msg("failed restoring backup folder")
} }