mirror of
https://github.com/goharbor/harbor.git
synced 2024-09-03 18:00:29 +02:00
1. Change down version to list to accept multi verstion value 2. Update search function use BFS to find migration path 2. Add test case Signed-off-by: DQ <dengq@vmware.com>
66 lines
2.1 KiB
Python
66 lines
2.1 KiB
Python
import yaml
|
|
import click
|
|
import importlib
|
|
import os
|
|
from collections import deque
|
|
|
|
class MigratioNotFound(Exception): ...
|
|
|
|
class MigrationVersion:
|
|
'''
|
|
The version used to migration
|
|
|
|
Arttribute:
|
|
name(str): version name like `1.0.0`
|
|
module: the python module object for a specific migration which contains migrate info, codes and templates
|
|
down_versions(list): previous versions that can migrated to this version
|
|
'''
|
|
def __init__(self, version: str):
|
|
self.name = version
|
|
self.module = importlib.import_module("migrations.version_{}".format(version.replace(".","_")))
|
|
|
|
@property
|
|
def down_versions(self):
|
|
return self.module.down_revisions
|
|
|
|
def read_conf(path):
|
|
with open(path) as f:
|
|
try:
|
|
d = yaml.safe_load(f)
|
|
except Exception as e:
|
|
click.echo("parse config file err, make sure your harbor config version is above 1.8.0", e)
|
|
exit(-1)
|
|
return d
|
|
|
|
def search(input_version: str, target_version: str) -> list :
|
|
"""
|
|
Find the migration path by BFS
|
|
Args:
|
|
input_version(str): The version migration start from
|
|
target_version(str): The target version migrated to
|
|
Returns:
|
|
list: the module of migrations in the upgrade path
|
|
"""
|
|
upgrade_path = []
|
|
next_version, visited, q = {}, set(), deque()
|
|
q.append(target_version)
|
|
found = False
|
|
while q: # BFS to find a valid path
|
|
version = MigrationVersion(q.popleft())
|
|
visited.add(version.name)
|
|
if version.name == input_version:
|
|
found = True
|
|
break # break loop cause migration path found
|
|
for v in version.down_versions:
|
|
next_version[v] = version.name
|
|
if v not in (visited.union(q)):
|
|
q.append(v)
|
|
|
|
if not found:
|
|
raise MigratioNotFound('no migration path found to target version')
|
|
|
|
current_version = MigrationVersion(input_version)
|
|
while current_version.name != target_version:
|
|
current_version = MigrationVersion(next_version[current_version.name])
|
|
upgrade_path.append(current_version)
|
|
return list(map(lambda x: x.module, upgrade_path)) |