Skip to content

Commit 624ba8c

Browse files
author
Pablo Rodriguez Nava
committed
MCO-2028: Add target OS version detection
Change package installation during kernel switches to derive the OS version from the target rpm-ostree deployment instead of the current running version. Treating the OS version as static caused failures during major version upgrades due to package discrepancies. This fix ensures package resolution targets the new OS version. Signed-off-by: Pablo Rodriguez Nava <git@amail.pablintino.com>
1 parent 15a0d2f commit 624ba8c

2 files changed

Lines changed: 53 additions & 5 deletions

File tree

pkg/daemon/rpm-ostree.go

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,38 @@ func (r *RpmOstreeClient) RebaseLayeredFromContainerStorage(podmanImageInfo *Pod
229229
return runRpmOstree("rebase", "--experimental", "ostree-unverified-image:containers-storage:"+podmanImageInfo.RepoDigest)
230230
}
231231

232+
// DeploymentVersion wraps rpm-ostree deployment information to provide
233+
// version checking methods similar to the osrelease package.
234+
type DeploymentVersion struct {
235+
// osName is the osname field from the deployment
236+
osName string
237+
// version is the version field from the deployment
238+
version string
239+
}
240+
241+
// NewTargetOSVersionFromDeployment creates a DeploymentVersion from the given deployment
242+
func NewTargetOSVersionFromDeployment(deployment *rpmostreeclient.Deployment) *DeploymentVersion {
243+
return &DeploymentVersion{
244+
osName: deployment.OSName,
245+
version: deployment.Version,
246+
}
247+
}
248+
249+
// BaseVersionMajor returns the first number in a `.` separated version.
250+
func (t *DeploymentVersion) BaseVersionMajor() string {
251+
return strings.Split(t.version, ".")[0]
252+
}
253+
254+
// IsEL is true if the OS is an Enterprise Linux variant of CoreOS
255+
func (t *DeploymentVersion) IsEL() bool {
256+
return t.osName == "rhcos" || t.osName == "scos"
257+
}
258+
259+
// IsEL10 is true if the target OS is RHCOS 10 or SCOS 10
260+
func (t *DeploymentVersion) IsEL10() bool {
261+
return t.IsEL() && (strings.HasPrefix(t.version, "10.") || t.version == "10")
262+
}
263+
232264
// patchPoliciesForContainerStorage temporarily overrides the container image policy visible
233265
// to rpm-ostreed to ensure pulls from the "containers-storage" transport are allowed for the
234266
// given image.

pkg/daemon/update.go

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1722,7 +1722,10 @@ func (dn *CoreOSDaemon) switchKernel(oldConfig, newConfig *mcfgv1.MachineConfig)
17221722
logSystem("Re-applying kernel type %s", newKtype)
17231723
}
17241724

1725-
kernelPackages := dn.getKernelPackagesForRelease()
1725+
kernelPackages, err := dn.getKernelPackagesForTargetRelease()
1726+
if err != nil {
1727+
return fmt.Errorf("failed to get kernel packages for target release: %w", err)
1728+
}
17261729
if newKtype == ctrlcommon.KernelTypeRealtime {
17271730
// Switch to RT kernel
17281731
args := []string{"override", "remove"}
@@ -1745,10 +1748,22 @@ func (dn *CoreOSDaemon) switchKernel(oldConfig, newConfig *mcfgv1.MachineConfig)
17451748
return fmt.Errorf("unhandled kernel type %s", newKtype)
17461749
}
17471750

1748-
// getKernelPackagesForRelease returns the list of kernel packaged for the running OS release.
1749-
func (dn *CoreOSDaemon) getKernelPackagesForRelease() releaseKernelPackages {
1751+
// getKernelPackagesForTargetRelease returns the list of kernel packaged for the running OS release.
1752+
func (dn *CoreOSDaemon) getKernelPackagesForTargetRelease() (releaseKernelPackages, error) {
17501753
// TODO: Drop this code and use https://github.com/coreos/rpm-ostree/issues/2542 instead
17511754

1755+
// Fetch the OS deployments to infer the target OS version from them
1756+
booted, staged, err := dn.NodeUpdaterClient.GetBootedAndStagedDeployment()
1757+
if err != nil {
1758+
return releaseKernelPackages{}, fmt.Errorf("error fetching OS deployments : %v", err)
1759+
}
1760+
1761+
// If there's a staged deployment the packages will be installed in it instead of in the current booted deployment
1762+
targetDeployment := booted
1763+
if staged != nil {
1764+
targetDeployment = staged
1765+
}
1766+
17521767
kernelPackages := releaseKernelPackages{
17531768
defaultKernel: []string{"kernel", "kernel-core", "kernel-modules", "kernel-modules-core", "kernel-modules-extra"},
17541769
hugePagesKernel: []string{"kernel-64k-core", "kernel-64k-modules", "kernel-64k-modules-core", "kernel-64k-modules-extra"},
@@ -1759,10 +1774,11 @@ func (dn *CoreOSDaemon) getKernelPackagesForRelease() releaseKernelPackages {
17591774

17601775
// RHEL10 early bugfix of OCPBUGS-62925
17611776
// RHEL10 doesn't ship with kernel-rt-kvm
1762-
if !dn.os.IsEL10() {
1777+
targetVersion := NewTargetOSVersionFromDeployment(targetDeployment)
1778+
if !targetVersion.IsEL10() {
17631779
kernelPackages.realtimeKernel = append(kernelPackages.realtimeKernel, "kernel-rt-kvm")
17641780
}
1765-
return kernelPackages
1781+
return kernelPackages, nil
17661782
}
17671783

17681784
// updateFiles writes files specified by the nodeconfig to disk. it also writes

0 commit comments

Comments
 (0)