From ca39b14bc2eb8f26c295e1f42afc3f6385e9d8f9 Mon Sep 17 00:00:00 2001 From: 0zyt Date: Sat, 24 Dec 2022 22:23:25 +0800 Subject: [PATCH 1/3] feat: support for rollback in case of error in intermediate steps Signed-off-by: 0zyt --- internal/pkg/upgrade/upgrade.go | 39 ++++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/internal/pkg/upgrade/upgrade.go b/internal/pkg/upgrade/upgrade.go index 8ac4e80f3..fea61e50c 100644 --- a/internal/pkg/upgrade/upgrade.go +++ b/internal/pkg/upgrade/upgrade.go @@ -137,30 +137,67 @@ func parseVersion(old, new string) (*semver.Version, *semver.Version, error) { // (2) rename `dtm-tmp` to current dtm file name. // (3) grant new dtm file execute permission. // (4) remove `dtm-bak` binary file. -// TODO(hxcGit): Support for rollback in case of error in intermediate steps + func applyUpgrade(workDir string) error { dtmFilePath := filepath.Join(workDir, dtmFileName) dtmBakFilePath := filepath.Join(workDir, dtmBakFileName) dtmTmpFilePath := filepath.Join(workDir, dtmTmpFileName) + updateProgress := 0 + defer func() { + for ; updateProgress >= 0; updateProgress-- { + switch updateProgress { + //If the error occur when step 1 (rename dtmFileName to `dtm-bak`), delete `dtm-tmp` + case 0: + if err := os.Remove(dtmTmpFilePath); err != nil { + log.Debugf("Dtm upgrade rollback error: %s", err.Error()) + } + + //the error occur in the step 2 + case 1: + if err := os.Rename(dtmBakFilePath, dtmFilePath); err != nil { + log.Debugf("Dtm upgrade rollback error: %s", err.Error()) + } + + //the error occur in the step 3 + case 2: + if err := os.Rename(dtmFilePath, dtmTmpFilePath); err != nil { + log.Debugf("Dtm upgrade rollback error: %s", err.Error()) + } + + //the error occur in the step 4 + case 3: + if err := os.Chmod(dtmFilePath, 0644); err != nil { + log.Debugf("Dtm upgrade rollback error: %s", err.Error()) + } + case 4: + //Successfully completed all step + return + } + } + }() if err := os.Rename(dtmFilePath, dtmBakFilePath); err != nil { return err } + updateProgress++ log.Debugf("Dtm upgrade: rename %s to dtm-bak successfully.", dtmFileName) if err := os.Rename(dtmTmpFilePath, dtmFilePath); err != nil { return err } + updateProgress++ log.Debugf("Dtm upgrade: rename dtm-tmp to %s successfully.", dtmFileName) if err := os.Chmod(dtmFilePath, 0755); err != nil { return err } + updateProgress++ log.Debugf("Dtm upgrade: grant %s execute permission successfully.", dtmFileName) if err := os.Remove(dtmBakFilePath); err != nil { return err } + updateProgress++ log.Debug("Dtm upgrade: remove dtm-bak successfully.") return nil From 2e496fba1fac00d0f5e9869b5f37ca2e741a7420 Mon Sep 17 00:00:00 2001 From: 0zyt Date: Tue, 27 Dec 2022 22:52:15 +0800 Subject: [PATCH 2/3] chore: change the step's number to iota for clear Signed-off-by: 0zyt --- internal/pkg/upgrade/upgrade.go | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/internal/pkg/upgrade/upgrade.go b/internal/pkg/upgrade/upgrade.go index fea61e50c..caf52dc84 100644 --- a/internal/pkg/upgrade/upgrade.go +++ b/internal/pkg/upgrade/upgrade.go @@ -16,6 +16,13 @@ import ( ) const ( + //the rollback step for the applyUpgrade function + STEP1 = iota + STEP2 + STEP3 + STEP4 + COMPLETED + assetName = "dtm-" + runtime.GOOS + "-" + runtime.GOARCH dtmTmpFileName = "dtm-tmp" dtmBakFileName = "dtm-bak" @@ -142,34 +149,34 @@ func applyUpgrade(workDir string) error { dtmFilePath := filepath.Join(workDir, dtmFileName) dtmBakFilePath := filepath.Join(workDir, dtmBakFileName) dtmTmpFilePath := filepath.Join(workDir, dtmTmpFileName) - updateProgress := 0 + updateProgress := STEP1 defer func() { for ; updateProgress >= 0; updateProgress-- { switch updateProgress { //If the error occur when step 1 (rename dtmFileName to `dtm-bak`), delete `dtm-tmp` - case 0: + case STEP1: if err := os.Remove(dtmTmpFilePath); err != nil { log.Debugf("Dtm upgrade rollback error: %s", err.Error()) } //the error occur in the step 2 - case 1: + case STEP2: if err := os.Rename(dtmBakFilePath, dtmFilePath); err != nil { log.Debugf("Dtm upgrade rollback error: %s", err.Error()) } //the error occur in the step 3 - case 2: + case STEP3: if err := os.Rename(dtmFilePath, dtmTmpFilePath); err != nil { log.Debugf("Dtm upgrade rollback error: %s", err.Error()) } //the error occur in the step 4 - case 3: + case STEP4: if err := os.Chmod(dtmFilePath, 0644); err != nil { log.Debugf("Dtm upgrade rollback error: %s", err.Error()) } - case 4: + case COMPLETED: //Successfully completed all step return } From 9be8875b1b42e8e368847e4a39354d6d33141121 Mon Sep 17 00:00:00 2001 From: 0zyt Date: Tue, 27 Dec 2022 22:58:11 +0800 Subject: [PATCH 3/3] chore: updateProgress to enum for clear at the loop Signed-off-by: 0zyt --- internal/pkg/upgrade/upgrade.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/pkg/upgrade/upgrade.go b/internal/pkg/upgrade/upgrade.go index caf52dc84..b402cb6a6 100644 --- a/internal/pkg/upgrade/upgrade.go +++ b/internal/pkg/upgrade/upgrade.go @@ -151,7 +151,7 @@ func applyUpgrade(workDir string) error { dtmTmpFilePath := filepath.Join(workDir, dtmTmpFileName) updateProgress := STEP1 defer func() { - for ; updateProgress >= 0; updateProgress-- { + for ; updateProgress >= STEP1; updateProgress-- { switch updateProgress { //If the error occur when step 1 (rename dtmFileName to `dtm-bak`), delete `dtm-tmp` case STEP1: