Skip to content

Commit

Permalink
Remove bin directory from gitignore
Browse files Browse the repository at this point in the history
  * Previously the bin directory was being ignored despite this being
    a logical place to contain scripts.  It has been re-enabled
    and the python script was added as a result.

Signed-off-by: Corey Osman <[email protected]>
  • Loading branch information
logicminds committed Dec 1, 2023
1 parent b34f3ec commit 8035e93
Show file tree
Hide file tree
Showing 2 changed files with 277 additions and 1 deletion.
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,3 @@ node_modules
.DS_Store
tmp
.idea
bin
277 changes: 277 additions & 0 deletions bin/generate_release_matrix.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,277 @@
#!/usr/bin/env python3
# Author: Corey Osman <[email protected]>
# Purpose: Geneate a list in specified format of all the linkerd charts by app version
# Usage: ./generate_release_matrix.py [--format=json|table|yaml] [--update_repo]
# Notes: Help determine which charts go with which app versions
# Notes: This is primary aimed at the stable release only, although a slight modification
# could yeild support for edge and Enterprise releases too.


import subprocess
import json
import yaml
try:
from tabulate import tabulate
except ImportError as e:
print("Please install tabulate: pip3 install tabulate")
exit(1)
import argparse

charts = [
# "linkerd2/linkerd2", # This makes the search return results for everything
"linkerd2/linkerd2-cni",
"linkerd2/linkerd-viz",
"linkerd2/linkerd-control-plane",
"linkerd2/linkerd-jaeger",
"linkerd2/linkerd-multicluster",
"linkerd2/linkerd-failover",
]

# these versions are old and do not have the proper mappings anways
ignored_y_versions = [6, 7, 8, 9]

# Manually map in the old chart, otherwise we get duplicates mixed in
linkerd2_map = {
'2.11': {
"linkerd2": {
"chart_name": "linkerd2/linkerd2",
"chart_version": "2.11.5",
"chart_url": "https://artifacthub.io/packages/helm/linkerd2/linkerd2/2.11"
}
},
'2.10': {
"linkerd2": {
"chart_name": "linkerd2/linkerd2",
"chart_version": "2.10.2",
"chart_url": "https://artifacthub.io/packages/helm/linkerd2/linkerd2/2.10"
}
}
}
# Manually map in the crds because there is no app version associated with them
crds_map = {
"2.12": {
"linkerd2-crds": {
"chart_name": "linkerd2/linkerd2-crds",
"chart_version": "1.6.1",
"chart_url": "https://artifacthub.io/packages/helm/linkerd2/linkerd2-crds/1.6.1"

}
},
"2.13": {
"linkerd2-crds": {
"chart_name": "linkerd2/linkerd2-crds",
"chart_version": "1.6.1",
"chart_url": "https://artifacthub.io/packages/helm/linkerd2/linkerd2-crds/1.6.1"
}
},
"2.14": {
"linkerd2-crds": {
"chart_name": "linkerd2/linkerd2-crds",
"chart_version": "1.8.0",
"chart_url": "https://artifacthub.io/packages/helm/linkerd2/linkerd2-crds/1.8.0"
}
},
}


def find_newest_versions(versions):
"""
Finds the newest version with the highest X value for a given Y version
Parameters:
versions (list): A list of version objects
Example: [('linkerd2/linkerd2', '2.11.5', 'stable-2.11.5'), ('linkerd2/linkerd2', '2.11.4', 'stable-2.11.4')
Returns:
list: A list of version objects
Example: [('linkerd2/linkerd2', '2.11.5', 'stable-2.11.5'),
('linkerd2/linkerd2', '2.10.2', 'stable-2.10.2'),
('linkerd2/linkerd2', '30.12.1', 'stable-2.14.3'),
('linkerd2/linkerd2', '30.8.5', 'stable-2.13.7'),
('linkerd2/linkerd2', '30.3.8', 'stable-2.12.6'),
('linkerd2/linkerd2', '2.11.5', 'stable-2.11.5'),
('linkerd2/linkerd2', '2.10.2', 'stable-2.10.2')]
"""
winners = {}
for entry in versions:
_, _, version, _ = entry
try:
x, y, z = map(int, version.split("-")[1].split("."))
if not y in ignored_y_versions:
current_winner = winners.get(
f"{x}.{y}.Z", {"x": x, "y": y, "z": z, version: version}
)
if current_winner["y"] == y and z >= current_winner["z"]:
# new winner
winners[f"{x}.{y}.Z"] = {"x": x, "y": y, "z": z, "version": version}

except IndexError:
next
except UnboundLocalError:
next

latest_versions = [v["version"] for v in winners.values()]
common_versions = []

for version in versions:
if version[2] in latest_versions:
common_versions.append(version)

return common_versions


def combine_charts_by_app_version(versions):
"""
Gathers all charts tuples under a single app version
Parameters:
versions (list): Raw list of versions tuples
[('linkerd2/linkerd-control-plane', '1.12.7', 'stable-2.13.7'),
('linkerd2/linkerd-control-plane', '1.16.4', 'stable-2.14.3'),
('linkerd2/linkerd-control-plane', '1.9.8', 'stable-2.12.6')]
Returns:
dict: versions object after combing under an app version.
{'stable-2.13.7':
{'linkerd2-crds':
{'chart_name': 'linkerd2/linkerd2-crds', 'chart_version': '1.6.1'},
'linkerd-jaeger': {
'chart_name': 'linkerd2/linkerd-jaeger', 'chart_version': '30.8.7'}
}
}
"""
combined_charts = {}
for chart, version, app_version, link in versions:
name = chart.split("/")[1]

if not app_version:
app_version = version
if not combined_charts.get(app_version):
combined_charts[app_version] = {}

combined_charts[app_version][name] = {
"chart_name": chart,
"chart_version": version,
"chart_url": link
}
# merge in the crds chart info if it exist for the version
x, y, _ = map(int, app_version.split("-")[1].split("."))
if y > 11:
combined_charts[app_version] = {**combined_charts[app_version], **crds_map[f"{x}.{y}"]}
else:
combined_charts[app_version] = {**combined_charts[app_version], **linkerd2_map[f"{x}.{y}"]}


# sorted(combined_charts.items(), key=lambda x: x[0] != "stable-2.11.5")
return combined_charts

def add_repo():
command = ["helm", "repo", "add", "linkerd2", " https://helm.linkerd.io/stable"]

try:
process = subprocess.Popen(
command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True
)
stdout, stderr = process.communicate()

except OSError as e:
print(f"Error: {e}")


def update_repo():
add_repo()

command = ["helm", "repo", "update", "linkerd2"]

try:
process = subprocess.Popen(
command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True
)
stdout, stderr = process.communicate()

except OSError as e:
print(f"Error: {e}")


def list_chart_versions(charts, latest_only=True):
"""
Fetches all the linkerd charts
Parameters:
charts (list): A list of chart names to fetch
Returns:
dict: A list of chart version tuples
Example: {('linkerd2/linkerd2', '2.11.5', 'stable-2.11.5')}
"""
all_versions = set()


for chart in charts:
# helm repo update linkerd2
command = ["helm", "search", "repo", chart, "--versions", "--output", "json"]

try:
process = subprocess.Popen(
command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True
)
stdout, stderr = process.communicate()

if process.returncode == 0:
chart_data = json.loads(stdout)
versions = [
(chart, item["version"], item["app_version"], f"https://artifacthub.io/packages/helm/{chart}/{item['version']}") for item in chart_data
]
if latest_only:
latest_versions = find_newest_versions(versions)
else:
latest_versions = versions

all_versions.update(latest_versions)
else:
print(f"Error: Failed to list chart versions for {chart}")
print(stderr)
except OSError as e:
print(f"Error: {e}")

return sorted(all_versions)


def print_output(data, format):
if format == "json":
print(json.dumps(data, indent=4))
elif format == "yaml":
print(yaml.dump(data, indent=4))
else:
#print("\nAvailable chart versions (table):")
headers = ["App Version", "Chart Name", "Chart Version"]
table = []
for app_version, charts in sorted(
data.items(), reverse=True
):
for chart_name, chard_data in charts.items():
table.append(
[app_version, chard_data["chart_name"], chard_data["chart_version"]]
)
print(tabulate(table, headers=headers, tablefmt="github"))
print("\n")
table = []


parser = argparse.ArgumentParser(description="List linkerd chart versions in various formats")
parser.add_argument(
"--format", default="table", choices=["table", "json", "yaml"], help="Desired Output format"
)
parser.add_argument('--update_repo', action='store_true', default=False, help="Add and update the linkerd2 repo")

args = parser.parse_args()

if args.update_repo:
update_repo()

all_versions = list_chart_versions(charts)
combined_charts_by_app_version = combine_charts_by_app_version(all_versions)
print_output(combined_charts_by_app_version, args.format)

0 comments on commit 8035e93

Please sign in to comment.