yesod-mirror/tools/helm_sync.py

104 lines
3 KiB
Python
Raw Normal View History

import yaml
import json
import requests
import sys
import os
from urllib.parse import urljoin
def load_yaml(path):
with open(path, 'r') as f:
return yaml.safe_load(f)
def fetch_index(repo_url):
index_url = urljoin(repo_url + '/', 'index.yaml')
print(f"Fetching index from {index_url}...")
try:
r = requests.get(index_url)
r.raise_for_status()
return yaml.safe_load(r.text)
except Exception as e:
print(f"Error fetching {index_url}: {e}")
return None
def main():
if len(sys.argv) < 2:
print("Usage: python helm_sync.py <path_to_chartfile.yaml> [output_lock_file]")
sys.exit(1)
chartfile_path = sys.argv[1]
lockfile_path = sys.argv[2] if len(sys.argv) > 2 else chartfile_path.replace('.yaml', '.lock.json')
print(f"Reading {chartfile_path}...")
chartfile = load_yaml(chartfile_path)
repos = {r['name']: r['url'] for r in chartfile.get('repositories', [])}
indices = {}
lock_data = {"charts": {}}
for req in chartfile.get('requires', []):
chart_ref = req['chart']
version = req['version']
if '/' not in chart_ref:
print(f"Invalid chart reference: {chart_ref}. Expected repo/name.")
continue
repo_name, chart_name = chart_ref.split('/', 1)
if repo_name not in repos:
print(f"Repository '{repo_name}' not found for chart {chart_ref}")
continue
repo_url = repos[repo_name]
if repo_name not in indices:
indices[repo_name] = fetch_index(repo_url)
index = indices[repo_name]
if not index:
print(f"Skipping {chart_ref} due to missing index.")
continue
entries = index.get('entries', {}).get(chart_name, [])
# Find exact version
matched_entry = None
for entry in entries:
if entry['version'] == version:
matched_entry = entry
break
if not matched_entry:
print(f"Version {version} not found for chart {chart_ref}")
continue
# Resolve URL
urls = matched_entry.get('urls', [])
if not urls:
print(f"No URLs found for {chart_ref} version {version}")
continue
# URL can be relative or absolute
chart_url = urls[0]
if not chart_url.startswith('http'):
chart_url = urljoin(repo_url + '/', chart_url)
digest = matched_entry.get('digest')
print(f"Resolved {chart_ref} {version} -> {chart_url}")
lock_data["charts"][chart_ref] = {
"version": version,
"url": chart_url,
"digest": digest
}
print(f"Writing lockfile to {lockfile_path}...")
with open(lockfile_path, 'w') as f:
json.dump(lock_data, f, indent=2, sort_keys=True)
f.write('\n')
if __name__ == "__main__":
main()