Skip to content

Commit 455dc8e

Browse files
authored
DKMS module installation (#514)
* New function added - prioritizes exact name matches over "provides" matches to prevent cross-package-type comparisons Signed-off-by: Teoh Suh Haw <suh.haw.teoh@intel.com> * Restore download.go Signed-off-by: Teoh Suh Haw <suh.haw.teoh@intel.com> * Restore ubuntu minimal yml Signed-off-by: Teoh Suh Haw <suh.haw.teoh@intel.com> * Add unit test for FilterCandidatesByPriorityWithTarget Signed-off-by: Teoh Suh Haw <suh.haw.teoh@intel.com> --------- Signed-off-by: Teoh Suh Haw <suh.haw.teoh@intel.com>
1 parent 3d9fba5 commit 455dc8e

File tree

3 files changed

+298
-13
lines changed

3 files changed

+298
-13
lines changed

image-templates/ubuntu24-x86_64-minimal-raw.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,4 +85,4 @@ systemConfig:
8585
version: "6.17"
8686
cmdline: "console=ttyS0,115200 console=tty0 loglevel=7"
8787
packages:
88-
- linux-image-generic-hwe-24.04
88+
- linux-image-generic-hwe-24.04

internal/ospackage/debutils/resolver.go

Lines changed: 87 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -430,6 +430,71 @@ func filterCandidatesByPriority(candidates []ospackage.PackageInfo) []ospackage.
430430
return filtered
431431
}
432432

433+
// filterCandidatesByPriorityWithTarget filters and sorts candidates, prioritizing exact name matches
434+
func filterCandidatesByPriorityWithTarget(candidates []ospackage.PackageInfo, targetName string) []ospackage.PackageInfo {
435+
log := logger.Logger()
436+
var filtered []ospackage.PackageInfo
437+
438+
// First pass: filter out blocked packages (priority < 0)
439+
for _, candidate := range candidates {
440+
if !shouldBlockPackage(candidate) {
441+
filtered = append(filtered, candidate)
442+
}
443+
}
444+
445+
// Sort by simple rule: exact name matches first, then provides matches
446+
sort.Slice(filtered, func(i, j int) bool {
447+
pkgI := filtered[i]
448+
pkgJ := filtered[j]
449+
450+
isExactI := pkgI.Name == targetName
451+
isExactJ := pkgJ.Name == targetName
452+
453+
// Simple rule: exact name matches always win over provides
454+
if isExactI != isExactJ {
455+
log.Debugf(" Exact match priority: %s (exact=%v) vs %s (exact=%v) -> %s wins",
456+
pkgI.Name, isExactI, pkgJ.Name, isExactJ,
457+
func() string {
458+
if isExactI {
459+
return pkgI.Name
460+
} else {
461+
return pkgJ.Name
462+
}
463+
}())
464+
return isExactI
465+
}
466+
467+
// For same type (both exact or both provides), use standard APT priority + version
468+
priorityI := getRepositoryPriority(pkgI.URL)
469+
priorityJ := getRepositoryPriority(pkgJ.URL)
470+
471+
// APT priority comparison
472+
if priorityI != priorityJ {
473+
return priorityI > priorityJ
474+
}
475+
476+
// Only compare versions for exact matches (avoid kernel vs dkms version comparison)
477+
if isExactI && isExactJ {
478+
versionCmp := compareVersions(pkgI.Version, pkgJ.Version) > 0
479+
log.Debugf(" Exact match version comparison: %s (%s) vs %s (%s) -> %s wins",
480+
pkgI.Name, pkgI.Version, pkgJ.Name, pkgJ.Version,
481+
func() string {
482+
if versionCmp {
483+
return pkgI.Name
484+
} else {
485+
return pkgJ.Name
486+
}
487+
}())
488+
return versionCmp
489+
}
490+
491+
// For provides matches, maintain stable order (don't compare different versioning schemes)
492+
return false
493+
})
494+
495+
return filtered
496+
}
497+
433498
// comparePriorityBehavior compares two packages based on APT priority behavior
434499
// Returns true if pkgA should be preferred over pkgB
435500
func comparePriorityBehavior(pkgA, pkgB ospackage.PackageInfo) bool {
@@ -1047,6 +1112,9 @@ func compareVersions(v1, v2 string) int {
10471112

10481113
// ResolvePackage finds the best matching package for a given package name
10491114
func ResolveTopPackageConflicts(want string, all []ospackage.PackageInfo) (ospackage.PackageInfo, bool) {
1115+
log := logger.Logger()
1116+
log.Debugf("ResolveTopPackageConflicts: Searching for package '%s' in %d available packages", want, len(all))
1117+
10501118
var candidates []ospackage.PackageInfo
10511119
for _, pi := range all {
10521120
// 1) exact name and version matched with .deb filenamae, e.g. acct_7.6.4-5+b1_amd64
@@ -1056,6 +1124,7 @@ func ResolveTopPackageConflicts(want string, all []ospackage.PackageInfo) (ospac
10561124
}
10571125
// 2) exact name, e.g. acct
10581126
if pi.Name == want {
1127+
log.Debugf(" Found EXACT NAME candidate: %s (version: %s)", pi.Name, pi.Version)
10591128
candidates = append(candidates, pi)
10601129
continue
10611130
}
@@ -1121,28 +1190,41 @@ func ResolveTopPackageConflicts(want string, all []ospackage.PackageInfo) (ospac
11211190
// Example: want="mail-transport-agent", pi.Provides=["mail-transport-agent"]
11221191
for _, provided := range pi.Provides {
11231192
if provided == want {
1193+
log.Debugf(" Found PROVIDES candidate: %s (version: %s, provides: %s)", pi.Name, pi.Version, provided)
11241194
candidates = append(candidates, pi)
11251195
break
11261196
}
11271197
}
11281198
}
11291199

1200+
log.Debugf("ResolveTopPackageConflicts: Found %d initial candidates for package '%s'", len(candidates), want)
1201+
for i, candidate := range candidates {
1202+
log.Debugf(" Candidate %d: %s (version: %s, provides: %v)", i+1, candidate.Name, candidate.Version, candidate.Provides)
1203+
}
1204+
11301205
if len(candidates) == 0 {
1206+
log.Debugf("ResolveTopPackageConflicts: No candidates found for package '%s'", want)
11311207
return ospackage.PackageInfo{}, false
11321208
}
11331209

1134-
// Filter out blocked packages (priority < 0)
1135-
candidates = filterCandidatesByPriority(candidates)
1210+
// Filter out blocked packages (priority < 0) and prioritize exact name matches
1211+
candidates = filterCandidatesByPriorityWithTarget(candidates, want)
1212+
log.Debugf("ResolveTopPackageConflicts: After priority filtering, %d candidates remain for package '%s'", len(candidates), want)
1213+
for i, candidate := range candidates {
1214+
log.Debugf(" Filtered candidate %d: %s (version: %s)", i+1, candidate.Name, candidate.Version)
1215+
}
11361216
if len(candidates) == 0 {
11371217
return ospackage.PackageInfo{}, false
11381218
}
11391219

11401220
// If we got an exact match in step (1), it's the only candidate
11411221
if len(candidates) == 1 && (candidates[0].Name == want || candidates[0].Name == want+".deb") {
1222+
log.Debugf("ResolveTopPackageConflicts: Selected exact match candidate: %s (version: %s)", candidates[0].Name, candidates[0].Version)
11421223
return candidates[0], true
11431224
}
11441225

11451226
// Candidates already sorted by filterCandidatesByPriority
1227+
log.Debugf("ResolveTopPackageConflicts: Selected best candidate: %s (version: %s) for package '%s'", candidates[0].Name, candidates[0].Version, want)
11461228
return candidates[0], true
11471229
}
11481230

@@ -1168,8 +1250,8 @@ func findAllCandidates(depName string, all []ospackage.PackageInfo) []ospackage.
11681250
}
11691251
}
11701252

1171-
// Apply APT priority filtering and sorting
1172-
filtered := filterCandidatesByPriority(candidates)
1253+
// Apply APT priority filtering and sorting with exact name preference
1254+
filtered := filterCandidatesByPriorityWithTarget(candidates, depName)
11731255
return filtered
11741256
}
11751257

@@ -1316,6 +1398,7 @@ func matchesRepoBase(parentBase []string, candidateBase string) bool {
13161398

13171399
func resolveMultiCandidates(parentPkg ospackage.PackageInfo, candidates []ospackage.PackageInfo) (ospackage.PackageInfo, error) {
13181400
// Filter out blocked packages (priority < 0) first
1401+
// All candidates should have the same name here, so no need for target-aware filtering
13191402
candidates = filterCandidatesByPriority(candidates)
13201403
if len(candidates) == 0 {
13211404
return ospackage.PackageInfo{}, fmt.Errorf("all candidates are blocked by negative priority")

0 commit comments

Comments
 (0)