Skip to content

Commit 950fc06

Browse files
stonezdjstonezdj
and
stonezdj
authored
Update migration tools (goharbor#20075)
update migration tools Signed-off-by: stonezdj <daojunz@vmware.com> Co-authored-by: stonezdj <daojunz@vmware.com>
1 parent d25f355 commit 950fc06

File tree

3 files changed

+89
-9
lines changed

3 files changed

+89
-9
lines changed

tools/migrate_chart/Dockerfile

+1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ ADD https://get.helm.sh/helm-v3.9.1-linux-amd64.tar.gz /
99
RUN tar zxvf /helm-v3.9.1-linux-amd64.tar.gz && \
1010
pip install click==7.1.2 && \
1111
pip install requests==2.24.0 && \
12+
pip install pyyaml && \
1213
chmod +x /migrate_chart.sh ./migrate_chart.py
1314

1415
ENTRYPOINT [ "/migrate_chart.py" ]

tools/migrate_chart/migrate_chart.py

+43-9
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,10 @@
33
import subprocess
44
import signal
55
import sys
6+
import os
67
from pathlib import Path
8+
import tarfile
9+
import yaml
710

811
import click
912
import requests
@@ -32,24 +35,51 @@ def graceful_exit(signum, frame):
3235
signal.signal(signal.SIGINT, graceful_exit)
3336
signal.signal(signal.SIGTERM, graceful_exit)
3437

38+
def find_chart_yaml(tar, path=''):
39+
# Iterate through the members of the tarfile
40+
for member in tar.getmembers():
41+
# If the member is a directory, recursively search within it
42+
if member.isdir():
43+
find_chart_yaml(tar, os.path.join(path, member.name))
44+
# If the member is a file and its name is 'chart.yaml', return its path
45+
if "Chart.yaml" in member.name:
46+
return os.path.join(path, member.name)
47+
48+
def read_chart_version(chart_tgz_path):
49+
# Open the chart tgz file
50+
with tarfile.open(chart_tgz_path, 'r:gz') as tar:
51+
# Find the path to chart.yaml within the tarball
52+
chart_yaml_path = find_chart_yaml(tar)
53+
if chart_yaml_path:
54+
# Extract the chart.yaml file
55+
chart_yaml_file = tar.extractfile(chart_yaml_path)
56+
if chart_yaml_file is not None:
57+
# Load the YAML content from chart.yaml
58+
chart_data = yaml.safe_load(chart_yaml_file)
59+
# Read the version from chart.yaml
60+
version = chart_data.get('version')
61+
name = chart_data.get('name')
62+
return name, version
63+
else:
64+
raise Exception("Failed to read chart.yaml from the chart tgz file. filename {}".format(chart_tgz_path))
65+
else:
66+
raise Exception("chart.yaml not found in the chart tgz file. filename {}".format(chart_tgz_path))
67+
3568
class ChartV2:
3669

3770
def __init__(self, filepath:Path):
3871
self.filepath = filepath
3972
self.project = self.filepath.parts[-2]
40-
parts = self.filepath.stem.split('-')
41-
flag = False
73+
self.name = ""
74+
self.version = ""
4275
try:
43-
for i in range(len(parts)-1, -1, -1):
44-
if parts[i][0].isnumeric() or ((parts[i][0]=='v' or parts[i][0]=='v') and parts[i][1].isnumeric()) :
45-
self.name, self.version = '-'.join(parts[:i]), '-'.join(parts[i:])
46-
flag = True
47-
break
48-
if not flag:
76+
self.name, self.version = read_chart_version(filepath)
77+
if self.name == "" or self.version == "" or self.name is None or self.version is None :
4978
raise Exception('chart name: {} is illegal'.format('-'.join(parts)))
5079
except Exception as e:
5180
click.echo("Skipped chart: {} due to illegal chart name. Error: {}".format(filepath, e), err=True)
5281
return
82+
5383
def __check_exist(self, hostname, username, password):
5484
return requests.get(CHART_URL_PATTERN.format(
5585
host=hostname,
@@ -90,6 +120,9 @@ def migrate(hostname, username, password):
90120
item_show_func=lambda x: "{}/{}:{} total errors: {}".format(x.project, x.name, x.version, len(errs)) if x else '') as bar:
91121
for chart in bar:
92122
try:
123+
if chart.name == "" or chart.version == "" :
124+
print("skip the chart {} has no name or version info".format(chart.filepath))
125+
continue
93126
result = chart.migrate(hostname, username, password)
94127
if result.stderr:
95128
errs.append("chart: {name}:{version} in {project} has err: {err}".format(
@@ -99,10 +132,11 @@ def migrate(hostname, username, password):
99132
err=result.stderr
100133
))
101134
except Exception as e:
102-
errs.append("chart: {name}:{version} in {project} has err: {err}".format(
135+
errs.append("chart: {name}:{version} in {project}, path {path} has err: {err}".format(
103136
name=chart.name,
104137
version=chart.version,
105138
project=chart.project,
139+
path = chart.filepath,
106140
err=e))
107141
click.echo("Migration is Done.")
108142
print_exist_errs()
+45
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
2+
import unittest
3+
import semver
4+
import tempfile
5+
import os
6+
import tarfile
7+
import shutil
8+
from pathlib import Path
9+
from migrate_chart import extract_chart_name_and_version
10+
from migrate_chart import read_chart_version
11+
12+
class TestExtractChartNameAndVersion(unittest.TestCase):
13+
def test_valid_chart_name(self):
14+
filepath = Path("my-project/my-chart-v1.0.0.tgz")
15+
name, version = extract_chart_name_and_version(filepath)
16+
self.assertEqual(name, "my-chart")
17+
self.assertEqual(version, "v1.0.0")
18+
19+
def test_invalid_chart_name(self):
20+
filepath = Path("my-project/mychart.tgz")
21+
name, version = extract_chart_name_and_version(filepath)
22+
self.assertIsNone(name)
23+
self.assertIsNone(version)
24+
25+
# def test_pure_digit(self):
26+
# filepath = Path("my-project/my-chart-8.0.0-5.tgz")
27+
# name, version = extract_chart_name_and_version(filepath)
28+
# self.assertEqual(name, "my-chart")
29+
# self.assertEqual(version, "8.0.0")
30+
31+
# def test_digit_startv(self):
32+
# filepath = Path("my-project/my-chart-v8.0.0-5.tgz")
33+
# name, version = extract_chart_name_and_version(filepath)
34+
# self.assertEqual(name, "my-chart")
35+
# self.assertEqual(version, "8.0.0")
36+
37+
def test_parse_version(self):
38+
temp_dir = tempfile.mkdtemp()
39+
file_name = "/Users/daojunz/Downloads/cert-manager/sample/cert-manager-8.0.0-5.tgz"
40+
name, version = read_chart_version(file_name)
41+
print(name)
42+
print(version)
43+
44+
if __name__ == '__main__':
45+
unittest.main()

0 commit comments

Comments
 (0)