2020 HELM_BLESSED_NAME_AND_CHECKSUMS ,
2121 HELM_BLESSED_VERSION ,
2222 HELM_DOWNLOAD_URL_STUB ,
23+ KUBECTL_BINARY_NAME ,
24+ KUBECTL_BLESSED_NAME_AND_CHECKSUMS ,
25+ KUBECTL_BLESSED_VERSION ,
26+ KUBECTL_DOWNLOAD_URL_STUB ,
2327)
2428from .graph import inquirer_create_network
2529from .network import copy_network_defaults , copy_scenario_defaults
@@ -147,7 +151,7 @@ def is_docker_desktop_running() -> tuple[bool, str]:
147151 except FileNotFoundError as err :
148152 return False , str (err )
149153
150- def is_kubectl_installed () -> tuple [bool , str ]:
154+ def is_kubectl_installed_and_offer_if_not () -> tuple [bool , str ]:
151155 try :
152156 version_result = subprocess .run (
153157 ["kubectl" , "version" , "--client" ],
@@ -163,8 +167,30 @@ def is_kubectl_installed() -> tuple[bool, str]:
163167 return True , location_result .stdout .strip ()
164168 else :
165169 return False , ""
166- except FileNotFoundError as err :
167- return False , str (err )
170+ except FileNotFoundError :
171+ print ()
172+ kubectl_answer = inquirer .prompt (
173+ [
174+ inquirer .Confirm (
175+ "install_kubectl" ,
176+ message = click .style (
177+ "Would you like Warnet to install Kubectl into your virtual environment?" ,
178+ fg = "blue" ,
179+ bold = True ,
180+ ),
181+ default = True ,
182+ ),
183+ ]
184+ )
185+ if kubectl_answer is None :
186+ msg = "Setup cancelled by user."
187+ click .secho (msg , fg = "yellow" )
188+ return False , msg
189+ if kubectl_answer ["install_kubectl" ]:
190+ click .secho (" Installing Kubectl..." , fg = "yellow" , bold = True )
191+ install_kubectl_rootlessly_to_venv ()
192+ return is_kubectl_installed_and_offer_if_not ()
193+ return False , "Please install Kubectl."
168194
169195 def is_helm_installed_and_offer_if_not () -> tuple [bool , str ]:
170196 try :
@@ -246,7 +272,7 @@ def check_installation(tool_info: ToolInfo) -> ToolStatus:
246272 )
247273 kubectl_info = ToolInfo (
248274 tool_name = "Kubectl" ,
249- is_installed_func = is_kubectl_installed ,
275+ is_installed_func = is_kubectl_installed_and_offer_if_not ,
250276 install_instruction = "Install kubectl." ,
251277 install_url = "https://kubernetes.io/docs/tasks/tools/install-kubectl/" ,
252278 )
@@ -446,7 +472,23 @@ def query_arch_from_uname(arch: str) -> Optional[str]:
446472 return None
447473
448474
449- def write_blessed_checksum (helm_filename : str , dest_path : str ):
475+ def write_blessed_kubectl_checksum (system : str , arch : str , dest_path : str ):
476+ checksum = next (
477+ (
478+ b ["checksum" ]
479+ for b in KUBECTL_BLESSED_NAME_AND_CHECKSUMS
480+ if b ["system" ] == system and b ["arch" ] == arch
481+ ),
482+ None ,
483+ )
484+ if checksum :
485+ with open (dest_path , "w" ) as f :
486+ f .write (checksum )
487+ else :
488+ click .secho ("Could not find a matching kubectl binary and checksum" , fg = "red" )
489+
490+
491+ def write_blessed_helm_checksum (helm_filename : str , dest_path : str ):
450492 checksum = next (
451493 (b ["checksum" ] for b in HELM_BLESSED_NAME_AND_CHECKSUMS if b ["name" ] == helm_filename ), None
452494 )
@@ -472,12 +514,12 @@ def verify_checksum(file_path, checksum_path):
472514 click .secho (" Checksum verified." , fg = "blue" )
473515
474516
475- def install_helm_to_venv ( helm_bin_path ):
517+ def install_to_venv ( bin_path , binary_name ):
476518 venv_bin_dir = os .path .join (sys .prefix , "bin" )
477- helm_dst_path = os .path .join (venv_bin_dir , HELM_BINARY_NAME )
478- shutil .move (helm_bin_path , helm_dst_path )
479- os .chmod (helm_dst_path , 0o755 )
480- click .secho (f" { HELM_BINARY_NAME } installed into { helm_dst_path } " , fg = "blue" )
519+ dst_path = os .path .join (venv_bin_dir , binary_name )
520+ shutil .move (bin_path , dst_path )
521+ os .chmod (dst_path , 0o755 )
522+ click .secho (f" { binary_name } installed into { dst_path } " , fg = "blue" )
481523
482524
483525def install_helm_rootlessly_to_venv ():
@@ -512,14 +554,14 @@ def install_helm_rootlessly_to_venv():
512554 checksum_path = os .path .join (temp_dir , f"{ helm_filename } .sha256" )
513555
514556 download_file (helm_url , helm_archive_path )
515- write_blessed_checksum (helm_filename , checksum_path )
557+ write_blessed_helm_checksum (helm_filename , checksum_path )
516558 verify_checksum (helm_archive_path , checksum_path )
517559
518560 # Extract Helm and install it in the virtual environment's bin folder
519561 with tarfile .open (helm_archive_path , "r:gz" ) as tar :
520562 tar .extractall (path = temp_dir )
521563 helm_bin_path = os .path .join (temp_dir , os_name + "-" + arch , HELM_BINARY_NAME )
522- install_helm_to_venv (helm_bin_path )
564+ install_to_venv (helm_bin_path , HELM_BINARY_NAME )
523565
524566 click .secho (
525567 f" { HELM_BINARY_NAME } { version } installed successfully to your virtual environment!\n " ,
@@ -529,3 +571,52 @@ def install_helm_rootlessly_to_venv():
529571 except Exception as e :
530572 click .secho (f"Error: { e } \n Could not install helm." , fg = "yellow" )
531573 sys .exit (1 )
574+
575+
576+ def install_kubectl_rootlessly_to_venv ():
577+ if not is_in_virtualenv ():
578+ click .secho (
579+ "Error: You are not in a virtual environment. Please activate a virtual environment and try again." ,
580+ fg = "yellow" ,
581+ )
582+ sys .exit (1 )
583+
584+ os_name = get_os_name_for_helm ()
585+ if os_name is None :
586+ click .secho (
587+ "Error: Could not determine the operating system of this computer." , fg = "yellow"
588+ )
589+ sys .exit (1 )
590+
591+ uname_arch = os .uname ().machine
592+ arch = query_arch_from_uname (uname_arch )
593+ if arch not in ["arm64" , "amd64" ]:
594+ click .secho (f"No Kubectl binary candidate for arch: { uname_arch } " , fg = "red" )
595+ sys .exit (1 )
596+
597+ uname_sys = os .uname ().sysname .lower ()
598+ if uname_sys not in ["linux" , "darwin" ]:
599+ click .secho (f"The following system is not supported: { uname_sys } " , fg = "red" )
600+ sys .exit (1 )
601+
602+ kubectl_url = f"{ KUBECTL_DOWNLOAD_URL_STUB } /{ uname_sys } /{ arch } /{ KUBECTL_BINARY_NAME } "
603+
604+ try :
605+ with tempfile .TemporaryDirectory () as temp_dir :
606+ binary_path = os .path .join (temp_dir , KUBECTL_BINARY_NAME )
607+ checksum_path = os .path .join (temp_dir , f"{ KUBECTL_BINARY_NAME } .sha256" )
608+
609+ download_file (kubectl_url , binary_path )
610+ write_blessed_kubectl_checksum (uname_sys , arch , checksum_path )
611+ verify_checksum (binary_path , checksum_path )
612+
613+ install_to_venv (binary_path , KUBECTL_BINARY_NAME )
614+
615+ click .secho (
616+ f" { KUBECTL_BINARY_NAME } { KUBECTL_BLESSED_VERSION } installed successfully to your virtual environment!\n " ,
617+ fg = "blue" ,
618+ )
619+
620+ except Exception as e :
621+ click .secho (f"Error: { e } \n Could not install helm." , fg = "yellow" )
622+ sys .exit (1 )
0 commit comments