Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 23 additions & 15 deletions pkg/daemon/update.go
Original file line number Diff line number Diff line change
Expand Up @@ -449,7 +449,7 @@ func podmanRemove(cid string) {
exec.Command("podman", "rm", "-f", cid).Run()
}

func pullExtensionsImage(podmanInterface PodmanInterface, imgURL string) error {
func pullExtensionsImage(podmanInterface PodmanInterface, imgURL string, background bool) error {
// Check if the image is present
podmanImageInfo, err := podmanInterface.GetPodmanImageInfoByReference(imgURL)
if err != nil || podmanImageInfo != nil {
Expand All @@ -465,11 +465,15 @@ func pullExtensionsImage(podmanInterface PodmanInterface, imgURL string) error {
args := []string{"pull", "-q"}
args = append(args, authArgs...)
args = append(args, imgURL)
_, err = pivotutils.RunExtBackground(numRetriesNetCommands, "podman", args...)
if background {
_, err = pivotutils.RunExtBackground(numRetriesNetCommands, "podman", args...)
} else {
_, err = pivotutils.RunExt(numRetriesNetCommands, "podman", args...)
}
return err
}

func podmanCopy(podmanInterface PodmanInterface, imgURL, osImageContentDir string) (err error) {
func podmanCopy(podmanInterface PodmanInterface, imgURL, osImageContentDir string, background bool) (err error) {
// make sure that osImageContentDir doesn't exist
os.RemoveAll(osImageContentDir)

Expand All @@ -488,7 +492,11 @@ func podmanCopy(podmanInterface PodmanInterface, imgURL, osImageContentDir strin
// copy the content from create container locally into a temp directory under /run/
cid := strings.TrimSpace(string(cidBuf))
args := []string{"cp", fmt.Sprintf("%s:/", cid), osImageContentDir}
_, err = pivotutils.RunExtBackground(numRetriesNetCommands, "podman", args...)
if background {
_, err = pivotutils.RunExtBackground(numRetriesNetCommands, "podman", args...)
} else {
_, err = pivotutils.RunExt(numRetriesNetCommands, "podman", args...)
}
if err != nil {
return
}
Expand All @@ -505,7 +513,7 @@ func podmanCopy(podmanInterface PodmanInterface, imgURL, osImageContentDir strin

// ExtractExtensionsImage extracts the OS extensions content in a temporary directory under /run/machine-os-extensions
// and returns the path on successful extraction
func (dn *CoreOSDaemon) ExtractExtensionsImage(imgURL string) (osExtensionsImageContentDir string, err error) {
func (dn *CoreOSDaemon) ExtractExtensionsImage(imgURL string, background bool) (osExtensionsImageContentDir string, err error) {
if err = os.MkdirAll(osExtensionsContentBaseDir, 0o755); err != nil {
err = fmt.Errorf("error creating directory %s: %w", osExtensionsContentBaseDir, err)
return
Expand All @@ -514,11 +522,11 @@ func (dn *CoreOSDaemon) ExtractExtensionsImage(imgURL string) (osExtensionsImage
if osExtensionsImageContentDir, err = os.MkdirTemp(osExtensionsContentBaseDir, "os-extensions-content-"); err != nil {
return
}
if err := pullExtensionsImage(dn.podmanInterface, imgURL); err != nil {
if err := pullExtensionsImage(dn.podmanInterface, imgURL, background); err != nil {
return osExtensionsImageContentDir, fmt.Errorf("error pulling extensions image %s: %w", imgURL, err)
}
// Extract the image using `podman cp`
return osExtensionsImageContentDir, podmanCopy(dn.podmanInterface, imgURL, osExtensionsImageContentDir)
return osExtensionsImageContentDir, podmanCopy(dn.podmanInterface, imgURL, osExtensionsImageContentDir, background)
}

// Remove pending deployment on OSTree based system
Expand All @@ -527,7 +535,7 @@ func removePendingDeployment() error {
}

// applyOSChanges extracts the OS image and adds coreos-extensions repo if we have either OS update or package layering to perform
func (dn *CoreOSDaemon) applyOSChanges(mcDiff machineConfigDiff, oldConfig, newConfig *mcfgv1.MachineConfig) (retErr error) {
func (dn *CoreOSDaemon) applyOSChanges(mcDiff machineConfigDiff, oldConfig, newConfig *mcfgv1.MachineConfig, firstBoot bool) (retErr error) {
// We previously did not emit this event when kargs changed, so we still don't
if mcDiff.osUpdate || mcDiff.extensions || mcDiff.kernelType || mcDiff.oclEnabled {
// We emitted this event before, so keep it
Expand Down Expand Up @@ -561,7 +569,7 @@ func (dn *CoreOSDaemon) applyOSChanges(mcDiff machineConfigDiff, oldConfig, newC
dn.nodeWriter.Eventf(corev1.EventTypeNormal, "OSUpdateStarted", reason)
}

if err := dn.applyLayeredOSChanges(mcDiff, oldConfig, newConfig); err != nil {
if err := dn.applyLayeredOSChanges(mcDiff, oldConfig, newConfig, firstBoot); err != nil {
return err
}

Expand Down Expand Up @@ -1273,7 +1281,7 @@ func (dn *Daemon) update(oldConfig, newConfig *mcfgv1.MachineConfig, skipCertifi
klog.Info("Applying OCL revert-specific OS changes")
}

if err := coreOSDaemon.applyOSChanges(*diff, oldConfig, newConfig); err != nil {
if err := coreOSDaemon.applyOSChanges(*diff, oldConfig, newConfig, firstBoot); err != nil {
// When ImageModeStatusReporting is enabled, update the `MachineConfigNodeUpdateOS` condition to report the experienced error
if imageModeStatusReportingEnabled {
mcnErr := upgrademonitor.GenerateAndApplyMachineConfigNodes(
Expand All @@ -1295,7 +1303,7 @@ func (dn *Daemon) update(oldConfig, newConfig *mcfgv1.MachineConfig, skipCertifi

defer func() {
if retErr != nil {
if err := coreOSDaemon.applyOSChanges(*diff, newConfig, oldConfig); err != nil {
if err := coreOSDaemon.applyOSChanges(*diff, newConfig, oldConfig, firstBoot); err != nil {
errs := kubeErrs.NewAggregate([]error{err, retErr})
retErr = fmt.Errorf("error rolling back changes to OS: %w", errs)
return
Expand Down Expand Up @@ -1449,13 +1457,13 @@ func (dn *Daemon) updateHypershift(oldConfig, newConfig *mcfgv1.MachineConfig, d

if dn.os.IsCoreOSVariant() {
coreOSDaemon := CoreOSDaemon{dn}
if err := coreOSDaemon.applyOSChanges(*diff, oldConfig, newConfig); err != nil {
if err := coreOSDaemon.applyOSChanges(*diff, oldConfig, newConfig, false); err != nil {
return err
}

defer func() {
if retErr != nil {
if err := coreOSDaemon.applyOSChanges(*diff, newConfig, oldConfig); err != nil {
if err := coreOSDaemon.applyOSChanges(*diff, newConfig, oldConfig, false); err != nil {
errs := kubeErrs.NewAggregate([]error{err, retErr})
retErr = fmt.Errorf("error rolling back changes to OS: %w", errs)
return
Expand Down Expand Up @@ -3219,7 +3227,7 @@ func (dn *Daemon) reboot(rationale string) error {
}

//nolint:gocyclo
func (dn *CoreOSDaemon) applyLayeredOSChanges(mcDiff machineConfigDiff, oldConfig, newConfig *mcfgv1.MachineConfig) (retErr error) {
func (dn *CoreOSDaemon) applyLayeredOSChanges(mcDiff machineConfigDiff, oldConfig, newConfig *mcfgv1.MachineConfig, firstBoot bool) (retErr error) {
// Override the computed diff if the booted state differs from the oldConfig
// https://issues.redhat.com/browse/OCPBUGS-2757
if mcDiff.osUpdate && dn.bootedOSImageURL == newConfig.Spec.OSImageURL {
Expand Down Expand Up @@ -3274,7 +3282,7 @@ func (dn *CoreOSDaemon) applyLayeredOSChanges(mcDiff machineConfigDiff, oldConfi
}
}

if osExtensionsContentDir, err = dn.ExtractExtensionsImage(newConfig.Spec.BaseOSExtensionsContainerImage); err != nil {
if osExtensionsContentDir, err = dn.ExtractExtensionsImage(newConfig.Spec.BaseOSExtensionsContainerImage, !firstBoot); err != nil {
// Report ImagePulledFromRegistry condition as false (failed)
if imageModeStatusReportingEnabled {
err := upgrademonitor.GenerateAndApplyMachineConfigNodes(
Expand Down
2 changes: 1 addition & 1 deletion pkg/daemon/update_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -962,7 +962,7 @@ func TestPodmanCopy_CreateContainerCall(t *testing.T) {

// Note: This test will fail at podmanRemove since we're only testing the interface call
// The function will return an error, but we can verify the CreatePodmanContainer was called correctly
err := podmanCopy(mockPodman, imgURL, osImageContentDir)
err := podmanCopy(mockPodman, imgURL, osImageContentDir, true)

// Verify the CreatePodmanContainer was called with correct parameters
expectedArgs := []string{"--net=none", "--annotation=org.openshift.machineconfigoperator.pivot=true"}
Expand Down