@@ -28,6 +28,9 @@ import (
2828 "github.com/sirupsen/logrus"
2929)
3030
31+ //APT package database location
32+ const dpkgStatusFile string = "var/lib/dpkg/status"
33+
3134type AptAnalyzer struct {
3235}
3336
@@ -53,7 +56,7 @@ func (a AptAnalyzer) getPackages(image pkgutil.Image) (map[string]util.PackageIn
5356 // invalid image directory path
5457 return packages , err
5558 }
56- statusFile := filepath .Join (path , "var/lib/dpkg/status" )
59+ statusFile := filepath .Join (path , dpkgStatusFile )
5760 if _ , err := os .Stat (statusFile ); err != nil {
5861 // status file does not exist in this layer
5962 return packages , nil
@@ -120,3 +123,61 @@ func parseLine(text string, currPackage string, packages map[string]util.Package
120123 }
121124 return currPackage
122125}
126+
127+ type AptLayerAnalyzer struct {
128+ }
129+
130+ func (a AptLayerAnalyzer ) Name () string {
131+ return "AptLayerAnalyzer"
132+ }
133+
134+ // AptDiff compares the packages installed by apt-get.
135+ func (a AptLayerAnalyzer ) Diff (image1 , image2 pkgutil.Image ) (util.Result , error ) {
136+ diff , err := singleVersionLayerDiff (image1 , image2 , a )
137+ return diff , err
138+ }
139+
140+ func (a AptLayerAnalyzer ) Analyze (image pkgutil.Image ) (util.Result , error ) {
141+ analysis , err := singleVersionLayerAnalysis (image , a )
142+ return analysis , err
143+ }
144+
145+ func (a AptLayerAnalyzer ) getPackages (image pkgutil.Image ) ([]map [string ]util.PackageInfo , error ) {
146+ var packages []map [string ]util.PackageInfo
147+ if _ , err := os .Stat (image .FSPath ); err != nil {
148+ // invalid image directory path
149+ return packages , err
150+ }
151+ statusFile := filepath .Join (image .FSPath , dpkgStatusFile )
152+ if _ , err := os .Stat (statusFile ); err != nil {
153+ // status file does not exist in this image
154+ return packages , nil
155+ }
156+ for _ , layer := range image .Layers {
157+ layerPackages := make (map [string ]util.PackageInfo )
158+ if _ , err := os .Stat (layer .FSPath ); err != nil {
159+ // invalid layer directory path
160+ return packages , err
161+ }
162+ statusFile := filepath .Join (layer .FSPath , dpkgStatusFile )
163+ if _ , err := os .Stat (statusFile ); err == nil {
164+ // this layer has a package database
165+ if file , err := os .Open (statusFile ); err == nil {
166+ // make sure it gets closed
167+ defer file .Close ()
168+
169+ // create a new scanner and read the file line by line
170+ scanner := bufio .NewScanner (file )
171+ var currPackage string
172+ for scanner .Scan () {
173+ currPackage = parseLine (scanner .Text (), currPackage , layerPackages )
174+ }
175+ } else {
176+ return packages , err
177+ }
178+ }
179+ packages = append (packages , layerPackages )
180+ }
181+
182+ return packages , nil
183+ }
0 commit comments