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:
@@ -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 {
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user