From 1c79f10ae8ce7735d3e460791465d1ad84c08a00 Mon Sep 17 00:00:00 2001 From: cmeng Date: Fri, 18 Aug 2023 21:40:42 +1200 Subject: [PATCH] fix(migrator): prevent duplicated migration EE-5777 (#10076) --- api/cmd/portainer/main.go | 5 +++++ api/datastore/migrator/migrator.go | 11 +++++++++++ 2 files changed, 16 insertions(+) diff --git a/api/cmd/portainer/main.go b/api/cmd/portainer/main.go index c8c29b751..854635878 100644 --- a/api/cmd/portainer/main.go +++ b/api/cmd/portainer/main.go @@ -20,6 +20,7 @@ import ( "github.com/portainer/portainer/api/database/models" "github.com/portainer/portainer/api/dataservices" "github.com/portainer/portainer/api/datastore" + "github.com/portainer/portainer/api/datastore/migrator" "github.com/portainer/portainer/api/demo" "github.com/portainer/portainer/api/docker" dockerclient "github.com/portainer/portainer/api/docker/client" @@ -119,11 +120,15 @@ func initDataStore(flags *portainer.CLIFlags, secretKey []byte, fileService port log.Fatal().Err(err).Msg("failed generating instance id") } + migratorInstance := migrator.NewMigrator(&migrator.MigratorParameters{}) + migratorCount := migratorInstance.GetMigratorCountOfCurrentAPIVersion() + // from MigrateData v := models.Version{ SchemaVersion: portainer.APIVersion, Edition: int(portainer.PortainerCE), InstanceID: instanceId.String(), + MigratorCount: migratorCount, } store.VersionService.UpdateVersion(&v) diff --git a/api/datastore/migrator/migrator.go b/api/datastore/migrator/migrator.go index a1e561175..e5229f5c6 100644 --- a/api/datastore/migrator/migrator.go +++ b/api/datastore/migrator/migrator.go @@ -148,6 +148,17 @@ func (m *Migrator) LatestMigrations() Migrations { return m.migrations[len(m.migrations)-1] } +func (m *Migrator) GetMigratorCountOfCurrentAPIVersion() int { + migratorCount := 0 + latestMigrations := m.LatestMigrations() + + if latestMigrations.Version.Equal(semver.MustParse(portainer.APIVersion)) { + migratorCount = len(latestMigrations.MigrationFuncs) + } + + return migratorCount +} + // !NOTE: Migration funtions should ideally be idempotent. // ! Which simply means the function can run over the same data many times but only transform it once. // ! In practice this really just means an extra check or two to ensure we're not destroying valid data.