Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Goto command support to handle dirty Database state #36

Merged
merged 4 commits into from
Oct 4, 2024

Conversation

venkat-iblox
Copy link

@venkat-iblox venkat-iblox commented Sep 23, 2024

This PR introduces improvements to the migration workflow by implementing robust handling for dirty states, effective failure management, and cleanup of newer migration files.

Goto command can handle the reversal of dirty DB state if the following args are set:

  • -force-dirty-handling: Lets the goto module know that the command has to handle the dirty state(required)
  • -cache-dir: The path where the current migrations(successfully executed) are stored. This is usually a mounted volume to the migration container and persists beyond the migration container's lifecycle.

Key Changes:

  1. Handle Dirty State:
  • Implements HandleDirtyState to apply the last successful migration when a dirty state is detected.
  1. Migration Failure Management:
  • Integrated HandleMigrationFailure to capture and store the last successful migration version in case of failure, ensuring available recovery options.
  1. File Cleanup:
  • Adds CleanupFiles to remove migration files with versions greater than the current migration version after successful execution, maintaining a clean working directory.

Added UTs for the new functionality.

@@ -35,4 +35,8 @@ var (

flagConfigDirectory = pflag.String("config.source", defaultConfigDirectory, "directory of the configuration file")
flagConfigFile = pflag.String("config.file", "", "configuration file name without extension")

// goto command flags
flagDirty = pflag.Bool("dirty", false, "migration is dirty")

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe this should be a verb instead of a noun. for example, 'handle-dirty', 'force-dirty-handling'. i'm open to the naming here but dirty by itself is not invocative about what this does.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

force-dirty-handling seems clear and concise on what it is supposedly doing

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That works for me

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would also suggest to update the description of the flag.

@venkat-iblox
Copy link
Author

venkat-iblox commented Sep 23, 2024

@daniel-garcia I am not able to add reviewers to this PR. Please review when you get a chance.
In the meantime, I will review the UT failure

@@ -35,4 +35,8 @@ var (

flagConfigDirectory = pflag.String("config.source", defaultConfigDirectory, "directory of the configuration file")
flagConfigFile = pflag.String("config.file", "", "configuration file name without extension")

// goto command flags
flagDirty = pflag.Bool("dirty", false, "migration is dirty")

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would also suggest to update the description of the flag.


// goto command flags
flagDirty = pflag.Bool("dirty", false, "migration is dirty")
flagPVCPath = pflag.String("intermediate-path", "", "path to the mounted volume which is used to copy the migration files")

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cannot it be any directory and not a PVC if used natively? If so, I would suggest to remove the PVC term.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I still see the mounted volume term here.

internal/cli/main.go Outdated Show resolved Hide resolved
internal/cli/main.go Outdated Show resolved Hide resolved
internal/cli/main.go Outdated Show resolved Hide resolved
migrate.go Outdated Show resolved Hide resolved
migrate.go Outdated Show resolved Hide resolved
migrate_test.go Outdated Show resolved Hide resolved
migrate_test.go Outdated Show resolved Hide resolved
migrate_test.go Outdated Show resolved Hide resolved
@venkat-iblox
Copy link
Author

@akleinib @daniel-garcia I have addressed comments except #36 (comment). To address this comment, we will need a broader work item to introduce new methods in the driver interface and its implementation across various supported drivers

@akleinib
Copy link

akleinib commented Oct 3, 2024

@akleinib @daniel-garcia I have addressed comments except #36 (comment). To address this comment, we will need a broader work item to introduce new methods in the driver interface and its implementation across various supported drivers

Maybe we can put a limitation that the new options only work if the file driver is used for source.

@venkat-iblox
Copy link
Author

@akleinib @daniel-garcia I have addressed comments except #36 (comment). To address this comment, we will need a broader work item to introduce new methods in the driver interface and its implementation across various supported drivers

Maybe we can put a limitation that the new options only work if the file driver is used for source.

Sure

ds *dirtyStateHandler
}

type dirtyStateHandler struct {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shan't we rename the structure to use something like Config rather than Handler?

@@ -744,6 +839,15 @@ func (m *Migrate) runMigrations(ret <-chan interface{}) error {
if migr.Body != nil {
m.logVerbosePrintf("Read and execute %v\n", migr.LogString())
if err := m.databaseDrv.Run(migr.BufferedBody); err != nil {
if m.dirtyStateConf != nil && m.dirtyStateConf.enable {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cannot we use IsDirtyHandlingEnabled() here?

func (m *Migrate) handleDirtyState() error {
// Perform the following actions when the database state is dirty
/*
1. Update the source driver to read the migrations from the mounted volume
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As before regarding mounted volume term used multiple times in this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use cache-dir

@@ -1414,3 +1417,282 @@ func equalDbSeq(t *testing.T, i int, expected migrationSequence, got *dStub.Stub
t.Fatalf("\nexpected sequence %v,\ngot %v, in %v", bs, got.MigrationSequence, i)
}
}

// Setting up temp directory to be used as the volume mount
func setupTempDir(t *testing.T) (string, func()) {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

}

for _, file := range test.copiedFiles {
if _, err := os.Stat(filepath.Join(destDir, file)); os.IsNotExist(err) {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ideally you want to check that "current.sql" hasn't been copied.

I don't know if using https://pkg.go.dev/os#ReadDir you can write a helper function returning all the files in a directory you can compare with an expected list of files. It would avoid in the various test-cases the two loops (one checking for existence, one checking for absence).

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think it would matter. current.sql is a project specific concept, migrate file driver doesn't know anything about things that don't match its pattern.

Copy link

@daniel-garcia daniel-garcia left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. The public interface (cli switches and behaviors) is in decent shape. We can address other concerns in a followup PR

@venkat-iblox venkat-iblox merged commit 13318b2 into infobloxopen:ib Oct 4, 2024
2 of 5 checks passed
@venkat-iblox venkat-iblox deleted the goto-command-changes branch October 4, 2024 00:21
venkat-iblox added a commit that referenced this pull request Oct 9, 2024
…own feature (#37)

* address comments

* address comments + new UTs

* address comments

* remove build files
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants