11#!/usr/bin/env python3
22import sys
33import re
4+
45from os .path import basename , dirname , join , exists
56from collections import OrderedDict
67from typing import Union
@@ -276,7 +277,17 @@ def get_info(host, *, users=None, connection=None):
276277 data ["role" ] = "hub" if discovery .get ("NTD_CFHUB" ) else "client"
277278
278279 data ["bin" ] = {}
279- for bin in ["dpkg" , "rpm" , "yum" , "apt" , "pkg" , "zypper" , "curl" ]:
280+ for bin in [
281+ "dpkg" ,
282+ "rpm" ,
283+ "yum" ,
284+ "apt" ,
285+ "pkg" ,
286+ "zypper" ,
287+ "curl" ,
288+ "wget" ,
289+ "sha256sum" ,
290+ ]:
280291 path = discovery .get ("NTD_{}" .format (bin .upper ()))
281292 if path :
282293 data ["bin" ][bin ] = path
@@ -432,7 +443,7 @@ def bootstrap_host(host_data, policy_server, *, connection=None, trust_server=Tr
432443def _package_from_list (tags , extension , packages ):
433444 artifacts = [Artifact (None , p ) for p in packages ]
434445 artifact = filter_artifacts (artifacts , tags , extension )[- 1 ]
435- return artifact .url
446+ return artifact .url , artifact
436447
437448
438449def _package_from_releases (
@@ -445,7 +456,7 @@ def _package_from_releases(
445456 release = releases .pick_version (version )
446457 if release is None :
447458 print ("Could not find a release for version {}" .format (version ))
448- return None
459+ return None , None
449460
450461 release .init_download ()
451462
@@ -455,7 +466,7 @@ def _package_from_releases(
455466 version , edition
456467 )
457468 )
458- return None
469+ return None , None
459470
460471 artifacts = release .find (tags , extension )
461472 if not artifacts :
@@ -464,13 +475,16 @@ def _package_from_releases(
464475 "hub" if "hub" in tags else "client"
465476 )
466477 )
467- return None
478+ return None , None
468479 artifact = artifacts [- 1 ]
469480 if remote_download :
470- return artifact .url
481+ return artifact .url , artifact
471482 else :
472- return download_package (
473- artifact .url , checksum = artifact .checksum , insecure = insecure
483+ return (
484+ download_package (
485+ artifact .url , checksum = artifact .checksum , insecure = insecure
486+ ),
487+ artifact ,
474488 )
475489
476490
@@ -514,13 +528,85 @@ def get_package_from_host_info(
514528 tags .extend (tag for tag in package_tags if tag != "msi" )
515529
516530 if packages is None : # No command line argument given
517- package = _package_from_releases (
531+ package , artifact = _package_from_releases (
518532 tags , extension , version , edition , remote_download , insecure
519533 )
520534 else :
521- package = _package_from_list (tags , extension , packages )
535+ package , artifact = _package_from_list (tags , extension , packages )
536+
537+ return package , artifact
522538
523- return package
539+
540+ def _remote_download (
541+ host , package , artifact , pkg_binary , insecure = False , connection = None
542+ ):
543+
544+ if not pkg_binary :
545+ return None
546+ if "sha256sum" not in pkg_binary :
547+ if not insecure :
548+ log .error (
549+ "Cannot check file integrity. sha256sum is not installed on host. Run with --insecure to skip"
550+ )
551+ return None
552+ log .warning (
553+ "Cannot check file integrity. sha256sum is not installed on host. Continuing due to insecure flag"
554+ )
555+
556+ if "wget" in pkg_binary :
557+ has_wget = True
558+ elif "curl" in pkg_binary :
559+ has_wget = False
560+ else :
561+ log .error (
562+ "Cannot download remotely. wget and/or curl are not installed on host"
563+ )
564+ return None
565+
566+ if not (artifact and artifact .checksum ):
567+ if not insecure :
568+ log .error (
569+ "Cannot check file integrity. No artifact associated with package '{}' found. Run with --insecure to skip" .format (
570+ package
571+ )
572+ )
573+ return None
574+ log .warning (
575+ "Cannot check file integrity. No artifact associated with package '{}' found. Continuing due to insecure flag" .format (
576+ package
577+ )
578+ )
579+
580+ cf_remote_dir = dirname (__file__ )
581+ script_path = join (cf_remote_dir , "remote-download.sh" )
582+ if not exists (script_path ):
583+ sys .exit ("%s does not exist" % script_path )
584+ scp (
585+ script_path ,
586+ host ,
587+ connection ,
588+ hide = True ,
589+ )
590+
591+ args = ""
592+ if insecure :
593+ args += "-I "
594+ if has_wget :
595+ args += "-W "
596+ if artifact :
597+ args += "-c {} " .format (artifact .checksum )
598+ args += package
599+
600+ ret = ssh_cmd (connection , "bash remote-download.sh {}" .format (args ), errors = True )
601+
602+ if ret is None :
603+ return None
604+ if insecure :
605+ log .warning (ret )
606+
607+ log .debug ("Successfully remotely installed package on host" )
608+
609+ return basename (package )
524610
525611
526612@auto_connect
@@ -552,9 +638,10 @@ def install_host(
552638 elif packages and len (packages ) == 1 :
553639 package = packages [0 ]
554640
641+ artifact = None
555642 if not package :
556643 try :
557- package = get_package_from_host_info (
644+ package , artifact = get_package_from_host_info (
558645 data .get ("package_tags" ),
559646 data .get ("bin" ),
560647 data .get ("arch" ),
@@ -574,19 +661,16 @@ def install_host(
574661 return 1
575662
576663 if remote_download :
577- if ("bin" not in data ) or ("curl" not in data ["bin" ]):
578- log .error (
579- "Couldn't download remotely. Curl is not installed on host '%s'" % host
580- )
581- return 1
582-
583- print ("Downloading '%s' on '%s' using curl" % (package , host ))
584- r = ssh_cmd (
585- cmd = "curl --fail -O {}" .format (package ), connection = connection , errors = True
664+ package = _remote_download (
665+ host ,
666+ package ,
667+ artifact ,
668+ data .get ("bin" ),
669+ connection = connection ,
670+ insecure = insecure ,
586671 )
587- if r is None :
672+ if package is None :
588673 return 1
589- package = basename (package )
590674 elif not getattr (connection , "is_local" , False ):
591675 scp (package , host , connection = connection )
592676 package = basename (package )
0 commit comments