/
githubmirror
/
etcd
Обзор
Документация
Войти
/
githubmirror
/
etcd
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
server/storage/schema/migration.go
108 строк
3 KB
upodroid
switch to an updated semver library
30 июл 2026, 13:41
30 июл 2026, 13:41
9d57202
Код
Авторство
О чём код?
// Copyright 2021 The etcd Authors // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package schema import ( "fmt" "github.com/Masterminds/semver/v3" "go.uber.org/zap" "go.etcd.io/etcd/api/v3/version" "go.etcd.io/etcd/server/v3/storage/backend" ) type migrationPlan []migrationStep func newPlan(lg *zap.Logger, current semver.Version, target semver.Version) (plan migrationPlan, err error) { current = trimToMinor(current) target = trimToMinor(target) if current.Major() != target.Major() { lg.Error("Changing major storage version is not supported", zap.String("storage-version", current.String()), zap.String("target-storage-version", target.String()), ) return plan, fmt.Errorf("changing major storage version is not supported") } for !current.Equal(&target) { isUpgrade := current.Minor() < target.Minor() changes, err := schemaChangesForVersion(current, isUpgrade) if err != nil { return plan, err } step := newMigrationStep(current, isUpgrade, changes) plan = append(plan, step) current = step.target } return plan, nil } func (p migrationPlan) Execute(lg *zap.Logger, tx backend.BatchTx) error { tx.LockOutsideApply() defer tx.Unlock() return p.unsafeExecute(lg, tx) } func (p migrationPlan) unsafeExecute(lg *zap.Logger, tx backend.UnsafeReadWriter) (err error) { for _, s := range p { err = s.unsafeExecute(lg, tx) if err != nil { return err } lg.Info("updated storage version", zap.String("new-storage-version", s.target.String())) } return nil } // migrationStep represents a single migrationStep of migrating etcd storage between two minor versions. type migrationStep struct { target semver.Version actions ActionList } func newMigrationStep(v semver.Version, isUpgrade bool, changes []schemaChange) (step migrationStep) { step.actions = make(ActionList, len(changes)) for i, change := range changes { if isUpgrade { step.actions[i] = change.upgradeAction() } else { step.actions[len(changes)-1-i] = change.downgradeAction() } } if isUpgrade { step.target = *semver.New(v.Major(), v.Minor()+1, 0, "", "") } else { step.target = *semver.New(v.Major(), v.Minor()-1, 0, "", "") } return step } // unsafeExecute is non thread-safe version of execute. func (s migrationStep) unsafeExecute(lg *zap.Logger, tx backend.UnsafeReadWriter) error { err := s.actions.unsafeExecute(lg, tx) if err != nil { return err } // Storage version is available since v3.6, downgrading target v3.5 should clean this field. if !s.target.LessThan(&version.V3_6) { UnsafeSetStorageVersion(tx, &s.target) } return nil } func trimToMinor(ver semver.Version) semver.Version { return *semver.New(ver.Major(), ver.Minor(), 0, "", "") }