@ -154,7 +154,10 @@ func AnalyzeLocalImage(imageName string, minSeverity types.Priority, endpoint, m
// Retrieve history.
log . Println ( "Retrieving image history" )
layerIDs , err := historyFromCommand ( imageName )
layerIDs , err := historyFromManifest ( tmpPath )
if err != nil {
layerIDs , err = historyFromCommand ( imageName )
}
if err != nil || len ( layerIDs ) == 0 {
return fmt . Errorf ( "Could not get image's history: %s" , err )
}
@ -269,7 +272,7 @@ func AnalyzeLocalImage(imageName string, minSeverity types.Priority, endpoint, m
fmt . Printf ( "%s No vulnerabilities matching the minimum severity level were detected in your image\n" , color . YellowString ( "NOTE:" ) )
} else {
return fmt . Errorf ( "A total of %d vulnerabilities have been detected in your image" , len ( vulnerabilities ) )
}
}
return nil
}
@ -306,6 +309,33 @@ func save(imageName, path string) error {
return nil
}
func historyFromManifest ( path string ) ( [ ] string , error ) {
mf , err := os . Open ( path + "/manifest.json" )
if err != nil {
return nil , err
}
defer mf . Close ( )
// https://github.com/docker/docker/blob/master/image/tarexport/tarexport.go#L17
type manifestItem struct {
Config string
RepoTags [ ] string
Layers [ ] string
}
var manifest [ ] manifestItem
if err = json . NewDecoder ( mf ) . Decode ( & manifest ) ; err != nil {
return nil , err
} else if len ( manifest ) != 1 {
return nil , err
}
var layers [ ] string
for _ , layer := range manifest [ 0 ] . Layers {
layers = append ( layers , strings . TrimSuffix ( layer , "/layer.tar" ) )
}
return layers , nil
}
func historyFromCommand ( imageName string ) ( [ ] string , error ) {
var stderr bytes . Buffer
cmd := exec . Command ( "docker" , "history" , "-q" , "--no-trunc" , imageName )