Debian: Use --showformat flag to get status of packages and ignore n(not-inst… (#484)

* 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.
This commit is contained in:
Xiuming Chen
2017-09-26 17:44:00 -07:00
committed by Kota Kanbe
parent 1095ebea24
commit e5eb8e42f5
2 changed files with 36 additions and 17 deletions

View File

@@ -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 {

View File

@@ -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)
}