mirror of
https://github.com/portainer/portainer.git
synced 2025-07-19 05:19:39 +02:00
feat(version): migrate version to semver [EE-3756] (#7693)
redisigned version bucket and migration code
This commit is contained in:
parent
4cfa584c7c
commit
583346321e
27 changed files with 747 additions and 509 deletions
|
@ -1,7 +1,13 @@
|
|||
package migrator
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/Masterminds/semver"
|
||||
"github.com/rs/zerolog/log"
|
||||
|
||||
portainer "github.com/portainer/portainer/api"
|
||||
"github.com/portainer/portainer/api/database/models"
|
||||
"github.com/portainer/portainer/api/dataservices/dockerhub"
|
||||
"github.com/portainer/portainer/api/dataservices/endpoint"
|
||||
"github.com/portainer/portainer/api/dataservices/endpointgroup"
|
||||
|
@ -25,7 +31,9 @@ import (
|
|||
type (
|
||||
// Migrator defines a service to migrate data after a Portainer version update.
|
||||
Migrator struct {
|
||||
currentDBVersion int
|
||||
currentDBVersion *models.Version
|
||||
migrations []Migrations
|
||||
|
||||
endpointGroupService *endpointgroup.Service
|
||||
endpointService *endpoint.Service
|
||||
endpointRelationService *endpointrelation.Service
|
||||
|
@ -49,7 +57,7 @@ type (
|
|||
|
||||
// MigratorParameters represents the required parameters to create a new Migrator instance.
|
||||
MigratorParameters struct {
|
||||
DatabaseVersion int
|
||||
CurrentDBVersion *models.Version
|
||||
EndpointGroupService *endpointgroup.Service
|
||||
EndpointService *endpoint.Service
|
||||
EndpointRelationService *endpointrelation.Service
|
||||
|
@ -74,8 +82,8 @@ type (
|
|||
|
||||
// NewMigrator creates a new Migrator.
|
||||
func NewMigrator(parameters *MigratorParameters) *Migrator {
|
||||
return &Migrator{
|
||||
currentDBVersion: parameters.DatabaseVersion,
|
||||
migrator := &Migrator{
|
||||
currentDBVersion: parameters.CurrentDBVersion,
|
||||
endpointGroupService: parameters.EndpointGroupService,
|
||||
endpointService: parameters.EndpointService,
|
||||
endpointRelationService: parameters.EndpointRelationService,
|
||||
|
@ -96,9 +104,112 @@ func NewMigrator(parameters *MigratorParameters) *Migrator {
|
|||
authorizationService: parameters.AuthorizationService,
|
||||
dockerhubService: parameters.DockerhubService,
|
||||
}
|
||||
|
||||
migrator.initMigrations()
|
||||
return migrator
|
||||
}
|
||||
|
||||
// Version exposes version of database
|
||||
func (migrator *Migrator) Version() int {
|
||||
return migrator.currentDBVersion
|
||||
func (m *Migrator) CurrentDBVersion() string {
|
||||
return m.currentDBVersion.SchemaVersion
|
||||
}
|
||||
|
||||
func (m *Migrator) CurrentDBEdition() portainer.SoftwareEdition {
|
||||
return portainer.SoftwareEdition(m.currentDBVersion.Edition)
|
||||
}
|
||||
|
||||
func (m *Migrator) CurrentSemanticDBVersion() *semver.Version {
|
||||
v, err := semver.NewVersion(m.currentDBVersion.SchemaVersion)
|
||||
if err != nil {
|
||||
log.Fatal().Stack().Err(err).Msg("failed to parse current version")
|
||||
}
|
||||
|
||||
return v
|
||||
}
|
||||
|
||||
func (m *Migrator) addMigrations(v string, funcs ...func() error) {
|
||||
m.migrations = append(m.migrations, Migrations{
|
||||
version: semver.MustParse(v),
|
||||
migrationFuncs: funcs,
|
||||
})
|
||||
}
|
||||
|
||||
func (m *Migrator) latestMigrations() Migrations {
|
||||
return m.migrations[len(m.migrations)-1]
|
||||
}
|
||||
|
||||
// !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.
|
||||
// ! This is not a hard rule though. Understand the limitations. A migration function may only run over
|
||||
// ! the data more than once if a new migration function is added and the version of your database schema is
|
||||
// ! the same. e.g. two developers working on the same version add two different functions for different things.
|
||||
// ! This increases the migration funcs count and so they all run again.
|
||||
|
||||
type Migrations struct {
|
||||
version *semver.Version
|
||||
migrationFuncs MigrationFuncs
|
||||
}
|
||||
|
||||
type MigrationFuncs []func() error
|
||||
|
||||
func (m *Migrator) initMigrations() {
|
||||
// !IMPORTANT: Do not be tempted to alter the order of these migrations.
|
||||
// ! Even though one of them looks out of order. Caused by history related
|
||||
// ! to maintaining two versions and releasing at different times
|
||||
|
||||
m.addMigrations("1.0.0", dbTooOldError) // default version found after migration
|
||||
|
||||
m.addMigrations("1.21",
|
||||
m.updateUsersToDBVersion18,
|
||||
m.updateEndpointsToDBVersion18,
|
||||
m.updateEndpointGroupsToDBVersion18,
|
||||
m.updateRegistriesToDBVersion18)
|
||||
|
||||
m.addMigrations("1.22", m.updateSettingsToDBVersion19)
|
||||
|
||||
m.addMigrations("1.22.1",
|
||||
m.updateUsersToDBVersion20,
|
||||
m.updateSettingsToDBVersion20,
|
||||
m.updateSchedulesToDBVersion20)
|
||||
|
||||
m.addMigrations("1.23",
|
||||
m.updateResourceControlsToDBVersion22,
|
||||
m.updateUsersAndRolesToDBVersion22)
|
||||
|
||||
m.addMigrations("1.24",
|
||||
m.updateTagsToDBVersion23,
|
||||
m.updateEndpointsAndEndpointGroupsToDBVersion23)
|
||||
|
||||
m.addMigrations("1.24.1", m.updateSettingsToDB24)
|
||||
|
||||
m.addMigrations("2.0",
|
||||
m.updateSettingsToDB25,
|
||||
m.updateStacksToDB24)
|
||||
|
||||
m.addMigrations("2.1", m.updateEndpointSettingsToDB25)
|
||||
m.addMigrations("2.2", m.updateStackResourceControlToDB27)
|
||||
m.addMigrations("2.6", m.migrateDBVersionToDB30)
|
||||
m.addMigrations("2.9", m.migrateDBVersionToDB32)
|
||||
m.addMigrations("2.9.2", m.migrateDBVersionToDB33)
|
||||
m.addMigrations("2.10.0", m.migrateDBVersionToDB34)
|
||||
m.addMigrations("2.9.3", m.migrateDBVersionToDB35)
|
||||
m.addMigrations("2.12", m.migrateDBVersionToDB36)
|
||||
m.addMigrations("2.13", m.migrateDBVersionToDB40)
|
||||
m.addMigrations("2.14", m.migrateDBVersionToDB50)
|
||||
m.addMigrations("2.15", m.migrateDBVersionToDB60)
|
||||
m.addMigrations("2.16", m.migrateDBVersionToDB70)
|
||||
m.addMigrations("2.16.1", m.migrateDBVersionToDB71)
|
||||
|
||||
// Add new migrations below...
|
||||
// One function per migration, each versions migration funcs in the same file.
|
||||
}
|
||||
|
||||
// Always is always run at the end of migrations
|
||||
func (m *Migrator) Always() error {
|
||||
// currently nothing to be done in CE... yet
|
||||
return nil
|
||||
}
|
||||
|
||||
func dbTooOldError() error {
|
||||
return errors.New("migrating from less than Portainer 1.21.0 is not supported, please contact Portainer support")
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue