Skip to content
This repository was archived by the owner on Mar 27, 2024. It is now read-only.

Commit dfb276a

Browse files
authored
Merge pull request #244 from davidcassany/rpm_differ_update
Try to use local rpm binary to query rpmdb
2 parents bca6c56 + 221b982 commit dfb276a

File tree

1 file changed

+74
-2
lines changed

1 file changed

+74
-2
lines changed

differs/rpm_diff.go

Lines changed: 74 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,14 @@ limitations under the License.
1717
package differs
1818

1919
import (
20+
"bufio"
2021
"bytes"
2122
"context"
23+
"errors"
2224
"fmt"
2325
"math/rand"
2426
"os"
27+
"os/exec"
2528
"path/filepath"
2629
"strconv"
2730
"strings"
@@ -40,6 +43,14 @@ import (
4043
"github.com/sirupsen/logrus"
4144
)
4245

46+
//RPM macros file location
47+
const rpmMacros string = "/usr/lib/rpm/macros"
48+
49+
//RPM command to extract packages from the rpm database
50+
var rpmCmd = []string{
51+
"rpm", "--nodigest", "--nosignature",
52+
"-qa", "--qf", "%{NAME}\t%{VERSION}\t%{SIZE}\n",
53+
}
4354
var letters = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
4455

4556
// daemonMutex is required to protect against other go-routines, as
@@ -87,7 +98,68 @@ func (a RPMAnalyzer) getPackages(image pkgutil.Image) (map[string]util.PackageIn
8798
}
8899
}
89100

90-
return rpmDataFromContainer(image)
101+
packages, err := rpmDataFromImageFS(image)
102+
if err != nil {
103+
logrus.Info("Running RPM binary from image in a container")
104+
return rpmDataFromContainer(image)
105+
}
106+
return packages, err
107+
}
108+
109+
// rpmDataFromImageFS runs a local rpm binary, if any, to query the image
110+
// rpmdb and returns a map of installed packages.
111+
func rpmDataFromImageFS(image pkgutil.Image) (map[string]util.PackageInfo, error) {
112+
packages := make(map[string]util.PackageInfo)
113+
// Check there is an executable rpm tool in host
114+
if err := exec.Command("rpm", "--version").Run(); err != nil {
115+
logrus.Warn("No RPM binary in host")
116+
return packages, err
117+
}
118+
dbPath, err := rpmDBPath(image.FSPath)
119+
if err != nil {
120+
logrus.Warnf("Couldn't find RPM database: %s", err.Error())
121+
return packages, err
122+
}
123+
cmdArgs := append([]string{"--root", image.FSPath, "--dbpath", dbPath}, rpmCmd[1:]...)
124+
out, err := exec.Command(rpmCmd[0], cmdArgs...).Output()
125+
if err != nil {
126+
logrus.Warnf("RPM call failed: %s", err.Error())
127+
return packages, err
128+
}
129+
output := strings.Split(string(out), "\n")
130+
return parsePackageData(output)
131+
}
132+
133+
// rpmDBPath tries to get the RPM database path from the /usr/lib/rpm/macros
134+
// file in the image rootfs.
135+
func rpmDBPath(rootFSPath string) (string, error) {
136+
imgMacrosFile, err := os.Open(filepath.Join(rootFSPath, rpmMacros))
137+
if err != nil {
138+
return "", err
139+
}
140+
defer imgMacrosFile.Close()
141+
142+
scanner := bufio.NewScanner(imgMacrosFile)
143+
for scanner.Scan() {
144+
line := strings.TrimSpace(scanner.Text())
145+
146+
// We are looking for a macro definition like (form openSUSE Leap):
147+
// %_dbpath %{_usr}/lib/sysimage/rpm
148+
if strings.HasPrefix(line, "%_dbpath") {
149+
fields := strings.Fields(line)
150+
if len(fields) < 2 {
151+
break
152+
}
153+
out, err := exec.Command("rpm", "-E", fields[1]).Output()
154+
if err != nil {
155+
return "", err
156+
}
157+
dbPath := strings.TrimRight(string(out), "\r\n")
158+
_, err = os.Stat(filepath.Join(rootFSPath, dbPath))
159+
return dbPath, err
160+
}
161+
}
162+
return "", errors.New("Failed parsing macros file")
91163
}
92164

93165
// rpmDataFromContainer runs image in a container, queries the data of
@@ -114,7 +186,7 @@ func rpmDataFromContainer(image pkgutil.Image) (map[string]util.PackageInfo, err
114186
defer logrus.Infof("Removing image %s", imageName)
115187

116188
contConf := godocker.Config{
117-
Entrypoint: []string{"rpm", "--nodigest", "--nosignature", "-qa", "--qf", "%{NAME}\t%{VERSION}\t%{SIZE}\n"},
189+
Entrypoint: rpmCmd,
118190
Image: imageName,
119191
}
120192

0 commit comments

Comments
 (0)