Skip to content
This repository was archived by the owner on Jan 23, 2026. It is now read-only.

Commit ee0b3f8

Browse files
committed
Implement function for getting latest compatible controller version
(cherry picked from commit 8024d36)
1 parent 99c4cc5 commit ee0b3f8

4 files changed

Lines changed: 80 additions & 9 deletions

File tree

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import aiohttp
2+
import click
3+
import semver
4+
from jumpstarter_cli_common.version import get_client_version
5+
from packaging.version import Version
6+
7+
8+
async def get_latest_compatible_controller_version(
9+
client_version: str | None = None,
10+
):
11+
if client_version is None:
12+
client_version = Version(get_client_version())
13+
14+
async with aiohttp.ClientSession(
15+
raise_for_status=True,
16+
) as session:
17+
try:
18+
async with session.get(
19+
"https://quay.io/api/v1/repository/jumpstarter-dev/helm/jumpstarter/tag/",
20+
timeout=aiohttp.ClientTimeout(total=30),
21+
) as resp:
22+
resp = await resp.json()
23+
except Exception as e:
24+
raise click.ClickException(f"Failed to fetch controller versions: {e}") from e
25+
26+
compatible = set()
27+
fallback = set()
28+
29+
if not isinstance(resp, dict) or "tags" not in resp or not isinstance(resp["tags"], list):
30+
raise click.ClickException("Unexpected response fetching controller version")
31+
32+
for tag in resp["tags"]:
33+
if not isinstance(tag, dict) or "name" not in tag:
34+
continue # Skip malformed tag entries
35+
36+
try:
37+
version = semver.VersionInfo.parse(tag["name"])
38+
except ValueError:
39+
continue # ignore invalid versions
40+
41+
if version.major == client_version.major and version.minor == client_version.minor:
42+
compatible.add(version)
43+
else:
44+
fallback.add(version)
45+
46+
if compatible:
47+
selected = max(compatible)
48+
elif fallback:
49+
selected = max(fallback)
50+
else:
51+
raise ValueError("No valid controller versions found in the repository")
52+
53+
return str(selected)

packages/jumpstarter-cli-admin/jumpstarter_cli_admin/install.py

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,12 @@
22

33
import asyncclick as click
44
from jumpstarter_cli_common.opt import opt_context, opt_kubeconfig
5-
from jumpstarter_cli_common.version import get_client_version
65
from jumpstarter_kubernetes import helm_installed, install_helm_chart
76

7+
from .controller import get_latest_compatible_controller_version
88
from jumpstarter.common.ipaddr import get_ip_address
99

1010

11-
def get_chart_version() -> str:
12-
client_version = get_client_version()
13-
parts = client_version.split(".")
14-
return f"{parts[0].replace('v', '')}.{parts[1]}.{parts[2]}"
15-
16-
1711
@click.command
1812
@click.option("--helm", type=str, help="Path or name of a helm executable", default="helm")
1913
@click.option("--name", type=str, help="The name of the chart installation", default="jumpstarter")
@@ -34,7 +28,7 @@ def get_chart_version() -> str:
3428
@click.option("--nodeport", "mode", flag_value="nodeport", help="Use Nodeport routing (recommended)", default=True)
3529
@click.option("--ingress", "mode", flag_value="ingress", help="Use a Kubernetes ingress")
3630
@click.option("--route", "mode", flag_value="route", help="Use an OpenShift route")
37-
@click.option("-v", "--version", help="The version of the service to install", default=get_chart_version())
31+
@click.option("-v", "--version", help="The version of the service to install", default=None)
3832
@opt_kubeconfig
3933
@opt_context
4034
async def install(
@@ -69,6 +63,9 @@ async def install(
6963
if router_endpoint is None:
7064
router_endpoint = f"router.{basedomain}:8083"
7165

66+
if version is None:
67+
version = await get_latest_compatible_controller_version()
68+
7269
click.echo(f'Installing Jumpstarter service v{version} in namespace "{namespace}" with Helm\n')
7370
click.echo(f"Chart URI: {chart}")
7471
click.echo(f"Chart Version: {version}")

packages/jumpstarter-cli-admin/pyproject.toml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,13 @@ authors = [{ name = "Kirk Brauer", email = "kbrauer@hatci.com" }]
66
readme = "README.md"
77
license = "Apache-2.0"
88
requires-python = ">=3.11"
9-
dependencies = ["jumpstarter-cli-common", "jumpstarter-kubernetes"]
9+
dependencies = [
10+
"aiohttp>=3.11.18",
11+
"jumpstarter-cli-common",
12+
"jumpstarter-kubernetes",
13+
"packaging>=25.0",
14+
"semver~=2.13",
15+
]
1016

1117
[dependency-groups]
1218
dev = [

uv.lock

Lines changed: 15 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)