From e5eb8e42f5e72112417779a2ca2c8f72236a7851 Mon Sep 17 00:00:00 2001 From: Xiuming Chen Date: Tue, 26 Sep 2017 17:44:00 -0700 Subject: [PATCH] =?UTF-8?q?Debian:=20Use=20--showformat=20flag=20to=20get?= =?UTF-8?q?=20status=20of=20packages=20and=20ignore=20n(not-inst=E2=80=A6?= =?UTF-8?q?=20(#484)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Use --showformat flag to get status of packages and ignore n(not-installed) and c(removed, only has config files remaining) packages. * Ignoring all packages that are not in 'Installed' status. * Simplify char escaping in the command. * Fix typo. --- scan/debian.go | 33 ++++++++++++++++++++++++--------- scan/debian_test.go | 20 ++++++++++++-------- 2 files changed, 36 insertions(+), 17 deletions(-) diff --git a/scan/debian.go b/scan/debian.go index 581f0917..b791d729 100644 --- a/scan/debian.go +++ b/scan/debian.go @@ -240,18 +240,32 @@ func (o *debian) rebootRequired() (bool, error) { func (o *debian) scanInstalledPackages() (models.Packages, models.Packages, error) { installed, updatable := models.Packages{}, models.Packages{} - r := o.exec("dpkg-query -W", noSudo) + r := o.exec(`dpkg-query -W -f='${binary:Package}\t${db:Status-Abbrev}\t${Version}\n'`, noSudo) if !r.isSuccess() { return nil, nil, fmt.Errorf("Failed to SSH: %s", r) } // e.g. - // curl 7.19.7-40.el6_6.4 - // openldap 2.4.39-8.el6 + // curl ii 7.47.0-1ubuntu2.2 + // openssh-server rc 1:7.2p2-4ubuntu2.2 lines := strings.Split(r.Stdout, "\n") for _, line := range lines { if trimmed := strings.TrimSpace(line); len(trimmed) != 0 { - name, version, err := o.parseScannedPackagesLine(trimmed) + name, status, version, err := o.parseScannedPackagesLine(trimmed) + packageStatus := status[1] + // Package status: + // n = Not-installed + // c = Config-files + // H = Half-installed + // U = Unpacked + // F = Half-configured + // W = Triggers-awaiting + // t = Triggers-pending + // i = Installed + if packageStatus != 'i' { + o.log.Debugf("%s package status is '%c', ignoring", name, packageStatus) + continue + } if err != nil { return nil, nil, fmt.Errorf( "Debian: Failed to parse package line: %s", line) @@ -286,21 +300,22 @@ func (o *debian) scanInstalledPackages() (models.Packages, models.Packages, erro return installed, updatable, nil } -var packageLinePattern = regexp.MustCompile(`^([^\t']+)\t(.+)$`) +var packageLinePattern = regexp.MustCompile(`^([^\t']+)\t(.+)\t(.+)$`) -func (o *debian) parseScannedPackagesLine(line string) (name, version string, err error) { +func (o *debian) parseScannedPackagesLine(line string) (name, status, version string, err error) { result := packageLinePattern.FindStringSubmatch(line) - if len(result) == 3 { + if len(result) == 4 { // remove :amd64, i386... name = result[1] if i := strings.IndexRune(name, ':'); i >= 0 { name = name[:i] } - version = result[2] + status = result[2] + version = result[3] return } - return "", "", fmt.Errorf("Unknown format: %s", line) + return "", "", "", fmt.Errorf("Unknown format: %s", line) } func (o *debian) aptGetUpdate() error { diff --git a/scan/debian_test.go b/scan/debian_test.go index f55f094f..f7cef683 100644 --- a/scan/debian_test.go +++ b/scan/debian_test.go @@ -34,23 +34,27 @@ func TestParseScannedPackagesLineDebian(t *testing.T) { var packagetests = []struct { in string name string + status string version string }{ - {"base-passwd 3.5.33", "base-passwd", "3.5.33"}, - {"bzip2 1.0.6-5", "bzip2", "1.0.6-5"}, - {"adduser 3.113+nmu3ubuntu3", "adduser", "3.113+nmu3ubuntu3"}, - {"bash 4.3-7ubuntu1.5", "bash", "4.3-7ubuntu1.5"}, - {"bsdutils 1:2.20.1-5.1ubuntu20.4", "bsdutils", "1:2.20.1-5.1ubuntu20.4"}, - {"ca-certificates 20141019ubuntu0.14.04.1", "ca-certificates", "20141019ubuntu0.14.04.1"}, - {"apt 1.0.1ubuntu2.8", "apt", "1.0.1ubuntu2.8"}, + {"base-passwd ii 3.5.33", "base-passwd", "ii ", "3.5.33"}, + {"bzip2 ii 1.0.6-5", "bzip2", "ii ", "1.0.6-5"}, + {"adduser ii 3.113+nmu3ubuntu3", "adduser", "ii ", "3.113+nmu3ubuntu3"}, + {"bash ii 4.3-7ubuntu1.5", "bash", "ii ", "4.3-7ubuntu1.5"}, + {"bsdutils ii 1:2.20.1-5.1ubuntu20.4", "bsdutils", "ii ", "1:2.20.1-5.1ubuntu20.4"}, + {"ca-certificates ii 20141019ubuntu0.14.04.1", "ca-certificates", "ii ", "20141019ubuntu0.14.04.1"}, + {"apt rc 1.0.1ubuntu2.8", "apt", "rc ", "1.0.1ubuntu2.8"}, } d := newDebian(config.ServerInfo{}) for _, tt := range packagetests { - n, v, _ := d.parseScannedPackagesLine(tt.in) + n, s, v, _ := d.parseScannedPackagesLine(tt.in) if n != tt.name { t.Errorf("name: expected %s, actual %s", tt.name, n) } + if s != tt.status { + t.Errorf("status: expected %s, actual %s", tt.status, s) + } if v != tt.version { t.Errorf("version: expected %s, actual %s", tt.version, v) }