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

pull/11653/head
Oscar Zhou 7 months ago committed by GitHub
parent 17561c1c0c
commit a755e6be15
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -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)

@ -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")

@ -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")
} }

Loading…
Cancel
Save