@@ -102,7 +102,7 @@ func (a RPMAnalyzer) getPackages(image pkgutil.Image) (map[string]util.PackageIn
102102
103103 packages , err := rpmDataFromImageFS (image )
104104 if err != nil {
105- logrus .Info ("Running RPM binary from image in a container" )
105+ logrus .Info ("Couldn't retrieve RPM data from extracted filesystem; running query in container" )
106106 return rpmDataFromContainer (image .Image )
107107 }
108108 return packages , err
@@ -111,30 +111,22 @@ func (a RPMAnalyzer) getPackages(image pkgutil.Image) (map[string]util.PackageIn
111111// rpmDataFromImageFS runs a local rpm binary, if any, to query the image
112112// rpmdb and returns a map of installed packages.
113113func rpmDataFromImageFS (image pkgutil.Image ) (map [string ]util.PackageInfo , error ) {
114- packages := make (map [string ]util.PackageInfo )
115- // Check there is an executable rpm tool in host
116- if err := exec .Command ("rpm" , "--version" ).Run (); err != nil {
117- logrus .Warn ("No RPM binary in host" )
118- return packages , err
119- }
120- dbPath , err := rpmDBPath (image .FSPath )
114+ dbPath , err := rpmEnvCheck (image .FSPath )
121115 if err != nil {
122116 logrus .Warnf ("Couldn't find RPM database: %s" , err .Error ())
123- return packages , err
124- }
125- cmdArgs := append ([]string {"--root" , image .FSPath , "--dbpath" , dbPath }, rpmCmd [1 :]... )
126- out , err := exec .Command (rpmCmd [0 ], cmdArgs ... ).Output ()
127- if err != nil {
128- logrus .Warnf ("RPM call failed: %s" , err .Error ())
129- return packages , err
117+ return nil , err
130118 }
131- output := strings .Split (string (out ), "\n " )
132- return parsePackageData (output )
119+ return rpmDataFromFS (image .FSPath , dbPath )
133120}
134121
135- // rpmDBPath tries to get the RPM database path from the /usr/lib/rpm/macros
136- // file in the image rootfs.
137- func rpmDBPath (rootFSPath string ) (string , error ) {
122+ // rpmEnvCheck checks there is an rpm binary in the host and tries to
123+ // get the RPM database path from the /usr/lib/rpm/macros file in the
124+ // image rootfs
125+ func rpmEnvCheck (rootFSPath string ) (string , error ) {
126+ if err := exec .Command ("rpm" , "--version" ).Run (); err != nil {
127+ logrus .Warn ("No RPM binary in host" )
128+ return "" , err
129+ }
138130 imgMacrosFile , err := os .Open (filepath .Join (rootFSPath , rpmMacros ))
139131 if err != nil {
140132 return "" , err
@@ -408,7 +400,7 @@ func (a RPMLayerAnalyzer) getPackages(image pkgutil.Image) ([]map[string]util.Pa
408400
409401 packages , err := rpmDataFromLayerFS (image )
410402 if err != nil {
411- logrus .Info ("Running RPM binary from image in a container" )
403+ logrus .Info ("Couldn't retrieve RPM data from extracted filesystem; running query in container" )
412404 return rpmDataFromLayeredContainers (image .Image )
413405 }
414406 return packages , err
@@ -418,37 +410,42 @@ func (a RPMLayerAnalyzer) getPackages(image pkgutil.Image) ([]map[string]util.Pa
418410// rpmdb and returns an array of maps of installed packages.
419411func rpmDataFromLayerFS (image pkgutil.Image ) ([]map [string ]util.PackageInfo , error ) {
420412 var packages []map [string ]util.PackageInfo
421- // Check there is an executable rpm tool in host
422- if err := exec .Command ("rpm" , "--version" ).Run (); err != nil {
423- logrus .Warn ("No RPM binary in host" )
424- return packages , err
425- }
426- dbPath , err := rpmDBPath (image .FSPath )
413+ dbPath , err := rpmEnvCheck (image .FSPath )
427414 if err != nil {
428415 logrus .Warnf ("Couldn't find RPM database: %s" , err .Error ())
429416 return packages , err
430417 }
431418 for _ , layer := range image .Layers {
432- layerPackages := make (map [string ]util.PackageInfo )
433- //query only layers that include the rpm database
434- if _ , err := os .Stat (filepath .Join (layer .FSPath , dbPath )); err == nil {
435- cmdArgs := append ([]string {"--root" , layer .FSPath , "--dbpath" , dbPath }, rpmCmd [1 :]... )
436- out , err := exec .Command (rpmCmd [0 ], cmdArgs ... ).Output ()
437- if err != nil {
438- logrus .Warnf ("RPM call failed: %s" , err .Error ())
439- return packages , err
440- }
441- layerPackages , err = parsePackageData (strings .Split (string (out ), "\n " ))
442- if err != nil {
443- return packages , err
444- }
419+ layerPackages , err := rpmDataFromFS (layer .FSPath , dbPath )
420+ if err != nil {
421+ return packages , err
445422 }
446423 packages = append (packages , layerPackages )
447424 }
448425
449426 return packages , nil
450427}
451428
429+ // rpmDataFromFS runs a local rpm binary to query the image
430+ // rpmdb and returns a map of installed packages.
431+ func rpmDataFromFS (fsPath string , dbPath string ) (map [string ]util.PackageInfo , error ) {
432+ packages := make (map [string ]util.PackageInfo )
433+ if _ , err := os .Stat (filepath .Join (fsPath , dbPath )); err == nil {
434+ cmdArgs := append ([]string {"--root" , fsPath , "--dbpath" , dbPath }, rpmCmd [1 :]... )
435+ out , err := exec .Command (rpmCmd [0 ], cmdArgs ... ).Output ()
436+ if err != nil {
437+ logrus .Warnf ("RPM call failed: %s" , err .Error ())
438+ return packages , err
439+ }
440+ output := strings .Split (string (out ), "\n " )
441+ packages , err := parsePackageData (output )
442+ if err != nil {
443+ return packages , err
444+ }
445+ }
446+ return packages , nil
447+ }
448+
452449// rpmDataFromLayeredContainers runs a tmp image in a container for each layer,
453450// queries the data of installed rpm packages and returns an array of maps of
454451// packages.
0 commit comments