Skip to content

Commit 1090984

Browse files
committed
move quickstart checks to python
1 parent 4a47270 commit 1090984

File tree

1 file changed

+222
-18
lines changed

1 file changed

+222
-18
lines changed

src/warnet/main.py

Lines changed: 222 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
11
import json
22
import os
3+
import platform
34
import random
45
import subprocess
56
import sys
7+
from dataclasses import dataclass
8+
from enum import Enum, auto
69
from importlib.resources import files
710
from pathlib import Path
11+
from typing import Callable
812

913
import click
1014
import inquirer
@@ -46,25 +50,225 @@ def cli():
4650
@cli.command()
4751
def quickstart():
4852
"""Setup warnet"""
53+
54+
class ToolStatus(Enum):
55+
Satisfied = auto()
56+
Unsatisfied = auto()
57+
58+
@dataclass
59+
class ToolInfo:
60+
tool_name: str
61+
is_installed_func: Callable[[], tuple[bool, str]]
62+
install_instruction: str
63+
install_url: str
64+
65+
__slots__ = ["tool_name", "is_installed_func", "install_instruction", "install_url"]
66+
67+
def is_minikube_installed() -> tuple[bool, str]:
68+
try:
69+
version_result = subprocess.run(
70+
["minikube", "version", "--short"],
71+
capture_output=True,
72+
text=True,
73+
)
74+
location_result = subprocess.run(
75+
["which", "minikube"],
76+
capture_output=True,
77+
text=True,
78+
)
79+
if version_result.returncode == 0 and location_result.returncode == 0:
80+
return True, location_result.stdout.strip()
81+
else:
82+
return False, ""
83+
except FileNotFoundError as err:
84+
return False, str(err)
85+
86+
def is_minikube_version_valid_on_darwin() -> tuple[bool, str]:
87+
try:
88+
version_result = subprocess.run(
89+
["minikube", "version", "--short"],
90+
capture_output=True,
91+
text=True,
92+
)
93+
location_result = subprocess.run(
94+
["which", "minikube"],
95+
capture_output=True,
96+
text=True,
97+
)
98+
if version_result.returncode == 0 and location_result.returncode == 0:
99+
version = version_result.stdout.strip().split()[-1] # Get the version number
100+
return version not in [
101+
"v1.32.0",
102+
"1.33.0",
103+
], f"{location_result.stdout.strip()} ({version})"
104+
else:
105+
return False, ""
106+
except FileNotFoundError as err:
107+
return False, str(err)
108+
109+
def is_platform_darwin() -> bool:
110+
return platform.system() == "Darwin"
111+
112+
def is_docker_installed() -> tuple[bool, str]:
113+
try:
114+
version_result = subprocess.run(["docker", "--version"], capture_output=True, text=True)
115+
location_result = subprocess.run(
116+
["which", "docker"],
117+
capture_output=True,
118+
text=True,
119+
)
120+
if version_result.returncode == 0 and location_result.returncode == 0:
121+
return True, location_result.stdout.strip()
122+
else:
123+
return False, ""
124+
except FileNotFoundError as err:
125+
return False, str(err)
126+
127+
def is_docker_desktop_running() -> tuple[bool, str]:
128+
try:
129+
version_result = subprocess.run(["docker", "info"], capture_output=True, text=True)
130+
location_result = subprocess.run(
131+
["which", "docker"],
132+
capture_output=True,
133+
text=True,
134+
)
135+
if version_result.returncode == 0 and location_result.returncode == 0:
136+
return "Docker Desktop" in version_result.stdout, location_result.stdout.strip()
137+
else:
138+
return False, ""
139+
except FileNotFoundError as err:
140+
return False, str(err)
141+
142+
def is_kubectl_installed() -> tuple[bool, str]:
143+
try:
144+
version_result = subprocess.run(
145+
["kubectl", "version", "--client"],
146+
capture_output=True,
147+
text=True,
148+
)
149+
location_result = subprocess.run(
150+
["which", "kubectl"],
151+
capture_output=True,
152+
text=True,
153+
)
154+
if version_result.returncode == 0 and location_result.returncode == 0:
155+
return True, location_result.stdout.strip()
156+
else:
157+
return False, ""
158+
except FileNotFoundError as err:
159+
return False, str(err)
160+
161+
def is_helm_installed() -> tuple[bool, str]:
162+
try:
163+
version_result = subprocess.run(["helm", "version"], capture_output=True, text=True)
164+
location_result = subprocess.run(
165+
["which", "helm"],
166+
capture_output=True,
167+
text=True,
168+
)
169+
if version_result.returncode == 0 and location_result.returncode == 0:
170+
return version_result.returncode == 0, location_result.stdout.strip()
171+
else:
172+
return False, ""
173+
except FileNotFoundError as err:
174+
return False, str(err)
175+
176+
def check_installation(tool_info: ToolInfo) -> ToolStatus:
177+
has_good_version, location = tool_info.is_installed_func()
178+
if not has_good_version:
179+
instruction_label = click.style(" Instruction: ", fg="yellow", bold=True)
180+
instruction_text = click.style(f"{tool_info.install_instruction}", fg="yellow")
181+
url_label = click.style(" URL: ", fg="yellow", bold=True)
182+
url_text = click.style(f"{tool_info.install_url}", fg="yellow")
183+
184+
click.secho(f" 💥 {tool_info.tool_name} is not installed. {location}", fg="yellow")
185+
click.echo(instruction_label + instruction_text)
186+
click.echo(url_label + url_text)
187+
return ToolStatus.Unsatisfied
188+
else:
189+
click.secho(f" ⭐️ {tool_info.tool_name} is satisfied: {location}", bold=False)
190+
return ToolStatus.Satisfied
191+
192+
docker_info = ToolInfo(
193+
tool_name="Docker",
194+
is_installed_func=is_docker_installed,
195+
install_instruction="Install Docker from Docker's official site.",
196+
install_url="https://docs.docker.com/engine/install/",
197+
)
198+
docker_desktop_info = ToolInfo(
199+
tool_name="Docker Desktop",
200+
is_installed_func=is_docker_desktop_running,
201+
install_instruction="Make sure Docker Desktop is installed and running.",
202+
install_url="https://docs.docker.com/desktop/",
203+
)
204+
kubectl_info = ToolInfo(
205+
tool_name="Kubectl",
206+
is_installed_func=is_kubectl_installed,
207+
install_instruction="Install kubectl.",
208+
install_url="https://kubernetes.io/docs/tasks/tools/install-kubectl/",
209+
)
210+
helm_info = ToolInfo(
211+
tool_name="Helm",
212+
is_installed_func=is_helm_installed,
213+
install_instruction="Install Helm from Helm's official site.",
214+
install_url="https://helm.sh/docs/intro/install/",
215+
)
216+
minikube_info = ToolInfo(
217+
tool_name="Minikube",
218+
is_installed_func=is_minikube_installed,
219+
install_instruction="Install Minikube from the official Minikube site.",
220+
install_url="https://minikube.sigs.k8s.io/docs/start/",
221+
)
222+
minikube_version_info = ToolInfo(
223+
tool_name="Minikube's version",
224+
is_installed_func=is_minikube_version_valid_on_darwin,
225+
install_instruction="Install the latest Minikube from the official Minikube site.",
226+
install_url="https://minikube.sigs.k8s.io/docs/start/",
227+
)
228+
229+
print("")
230+
print(" ╭───────────────────────────────────╮")
231+
print(" │ Welcome to the Warnet Quickstart │")
232+
print(" ╰───────────────────────────────────╯")
233+
print("")
234+
print(" Let's find out if your system has what it takes to run Warnet...")
235+
print("")
236+
49237
try:
50-
# Requirements checks
51-
with subprocess.Popen(
52-
["/bin/bash", str(QUICK_START_PATH)],
53-
stdout=subprocess.PIPE,
54-
stderr=subprocess.STDOUT,
55-
universal_newlines=True,
56-
env=dict(os.environ, TERM="xterm-256color"),
57-
) as process:
58-
if process.stdout:
59-
for line in iter(process.stdout.readline, ""):
60-
click.echo(line, nl=False)
61-
return_code = process.wait()
62-
if return_code != 0:
63-
click.secho(
64-
f"Quick start script failed with return code {return_code}", fg="red", bold=True
65-
)
66-
click.secho("Install missing requirements before proceeding", fg="yellow")
67-
return False
238+
questions = [
239+
inquirer.List(
240+
"platform",
241+
message=click.style("Which platform would you like to use?", fg="blue", bold=True),
242+
choices=["Minikube", "Docker Desktop"],
243+
)
244+
]
245+
answers = inquirer.prompt(questions)
246+
247+
check_results: list[ToolStatus] = []
248+
if answers:
249+
if answers["platform"] == "Docker Desktop":
250+
check_results.append(check_installation(docker_info))
251+
check_results.append(check_installation(docker_desktop_info))
252+
check_results.append(check_installation(kubectl_info))
253+
check_results.append(check_installation(helm_info))
254+
elif answers["platform"] == "Minikube":
255+
check_results.append(check_installation(docker_info))
256+
check_results.append(check_installation(minikube_info))
257+
if is_platform_darwin():
258+
check_results.append(check_installation(minikube_version_info))
259+
check_results.append(check_installation(kubectl_info))
260+
check_results.append(check_installation(helm_info))
261+
else:
262+
click.secho("Please re-run Quickstart.", fg="yellow")
263+
sys.exit(1)
264+
265+
if ToolStatus.Unsatisfied in check_results:
266+
click.secho(
267+
"Please fix the installation issues above and try quickstart again.", fg="yellow"
268+
)
269+
sys.exit(1)
270+
else:
271+
click.secho(" ⭐️ Warnet prerequisites look good.\n")
68272

69273
# New project setup
70274
questions = [

0 commit comments

Comments
 (0)