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 {