Skip to content

Commit

Permalink
Merge pull request #3583 from cgwalters/no-legacy-osupdate
Browse files Browse the repository at this point in the history
MCO MCO-424: daemon: Remove old legacy OS update path
  • Loading branch information
openshift-merge-robot authored Jul 20, 2023
2 parents 2bcdd7f + 85b297c commit e91b573
Show file tree
Hide file tree
Showing 3 changed files with 7 additions and 167 deletions.
24 changes: 2 additions & 22 deletions pkg/daemon/daemon.go
Original file line number Diff line number Diff line change
Expand Up @@ -1700,30 +1700,10 @@ func (dn *Daemon) checkStateOnFirstRun() error {
if !osMatch {
logSystem("Bootstrap pivot required to: %s", targetOSImageURL)

// Check to see if we have a layered/new format image
isLayeredImage, err := dn.NodeUpdaterClient.IsBootableImage(targetOSImageURL)
if err != nil {
return fmt.Errorf("error checking type of target image: %w", err)
if err := dn.updateLayeredOS(state.currentConfig); err != nil {
return err
}

if isLayeredImage {
// If this is a new format image, we don't have to extract it,
// we can just update it the proper way
if err := dn.updateLayeredOS(state.currentConfig); err != nil {
return err
}
} else {
osImageContentDir, err := ExtractOSImage(targetOSImageURL)
if err != nil {
return err
}
if err := dn.updateOS(state.currentConfig, osImageContentDir); err != nil {
return err
}
if err := os.RemoveAll(osImageContentDir); err != nil {
return err
}
}
return dn.reboot(fmt.Sprintf("Node will reboot into config %v", state.currentConfig.GetName()))
}
logSystem("No bootstrap pivot required; unlinking bootstrap node annotations")
Expand Down
14 changes: 0 additions & 14 deletions pkg/daemon/rpm-ostree.go
Original file line number Diff line number Diff line change
Expand Up @@ -282,20 +282,6 @@ func (r *RpmOstreeClient) Rebase(imgURL, osImageContentDir string) (changed bool
return
}

// IsBootableImage determines if the image is a bootable (new container formet) image, or a wrapper (old container format)
func (r *RpmOstreeClient) IsBootableImage(imgURL string) (bool, error) {

var isBootableImage string
var imageData *types.ImageInspectInfo
var err error
if imageData, _, err = imageInspect(imgURL); err != nil {
return false, err
}
isBootableImage = imageData.Labels["ostree.bootable"]

return isBootableImage == "true", nil
}

// RpmOstreeIsNewEnoughForLayering returns true if the version of rpm-ostree on the
// host system is new enough for layering.
// VersionData represents the static information about rpm-ostree.
Expand Down
136 changes: 5 additions & 131 deletions pkg/daemon/update.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ const (
// fipsFile is the file to check if FIPS is enabled
fipsFile = "/proc/sys/crypto/fips_enabled"
extensionsRepo = "/etc/yum.repos.d/coreos-extensions.repo"
osImageContentBaseDir = "/run/mco-machine-os-content/"
osExtensionsContentBaseDir = "/run/mco-extensions/"

// These are the actions for a node to take after applying config changes. (e.g. a new machineconfig is applied)
Expand Down Expand Up @@ -160,17 +159,8 @@ func (dn *Daemon) compareMachineConfig(oldConfig, newConfig *mcfgv1.MachineConfi
}

// addExtensionsRepo adds a repo into /etc/yum.repos.d/ which we use later to
// install extensions and rt-kernel
func addExtensionsRepo(osImageContentDir string) error {
repoContent := "[coreos-extensions]\nenabled=1\nmetadata_expire=1m\nbaseurl=" + osImageContentDir + "/extensions/\ngpgcheck=0\nskip_if_unavailable=False\n"
return writeFileAtomicallyWithDefaults(extensionsRepo, []byte(repoContent))
}

// addLayeredExtensionsRepo adds a repo into /etc/yum.repos.d/ which we use later to
// install extensions and rt-kernel. This is separate from addExtensionsRepo because when we're
// extracting only the extensions container (because with the new format images they are packaged separately),
// we extract to a different location
func addLayeredExtensionsRepo(extensionsImageContentDir string) error {
// install extensions (additional packages).
func addExtensionsRepo(extensionsImageContentDir string) error {
repoContent := "[coreos-extensions]\nenabled=1\nmetadata_expire=1m\nbaseurl=" + extensionsImageContentDir + "/usr/share/rpm-ostree/extensions/\ngpgcheck=0\nskip_if_unavailable=False\n"
return writeFileAtomicallyWithDefaults(extensionsRepo, []byte(repoContent))
}
Expand Down Expand Up @@ -228,40 +218,6 @@ func podmanCopy(imgURL, osImageContentDir string) (err error) {
return
}

// ExtractOSImage extracts OS image content in a temporary directory under /run/machine-os-content/
// and returns the path on successful extraction.
// Note that since we do this in the MCD container, cluster proxy configuration must also be injected
// into the container. See the MCD daemonset.
func ExtractOSImage(imgURL string) (osImageContentDir string, err error) {
var registryConfig []string
if _, err := os.Stat(kubeletAuthFile); err == nil {
registryConfig = append(registryConfig, "--registry-config", kubeletAuthFile)
}
if err = os.MkdirAll(osImageContentBaseDir, 0o755); err != nil {
err = fmt.Errorf("error creating directory %s: %w", osImageContentBaseDir, err)
return
}

if osImageContentDir, err = os.MkdirTemp(osImageContentBaseDir, "os-content-"); err != nil {
return
}

// Extract the image
args := []string{"image", "extract", "-v", "10", "--path", "/:" + osImageContentDir}
args = append(args, registryConfig...)
args = append(args, imgURL)
if _, err = pivotutils.RunExtBackground(cmdRetriesCount, "oc", args...); err != nil {
// Workaround fixes for the environment where oc image extract fails.
// See https://bugzilla.redhat.com/show_bug.cgi?id=1862979
klog.Infof("Falling back to using podman cp to fetch OS image content")
if err = podmanCopy(imgURL, osImageContentDir); err != nil {
return
}
}

return
}

// ExtractExtensionsImage extracts the OS extensions content in a temporary directory under /run/machine-os-extensions
// and returns the path on successful extraction
func ExtractExtensionsImage(imgURL string) (osExtensionsImageContentDir string, err error) {
Expand Down Expand Up @@ -325,24 +281,10 @@ func (dn *CoreOSDaemon) applyOSChanges(mcDiff machineConfigDiff, oldConfig, newC
dn.nodeWriter.Eventf(corev1.EventTypeNormal, "OSUpdateStarted", mcDiff.osChangesString())
}

// The steps from here on are different depending on the image type, so check the image type
isLayeredImage, err := dn.NodeUpdaterClient.IsBootableImage(newConfig.Spec.OSImageURL)
if err != nil {
return fmt.Errorf("error checking type of update image: %w", err)
if err := dn.applyLayeredOSChanges(mcDiff, oldConfig, newConfig); err != nil {
return err
}

// TODO(jkyros): we can remove the format check and simplify this once we retire the "old format" images
if isLayeredImage {
// If it's a layered/bootable image, then apply it the "new" way
if err := dn.applyLayeredOSChanges(mcDiff, oldConfig, newConfig); err != nil {
return err
}
} else {
// Otherwise fall back to the old way -- we can take this out someday when it goes away
if err := dn.applyLegacyOSChanges(mcDiff, oldConfig, newConfig); err != nil {
return err
}
}
if dn.nodeWriter != nil {
var nodeName string
var nodeObjRef corev1.ObjectReference
Expand Down Expand Up @@ -1997,7 +1939,7 @@ func (dn *CoreOSDaemon) applyLayeredOSChanges(mcDiff machineConfigDiff, oldConfi
// Delete extracted OS image once we are done.
defer os.RemoveAll(osExtensionsContentDir)

if err := addLayeredExtensionsRepo(osExtensionsContentDir); err != nil {
if err := addExtensionsRepo(osExtensionsContentDir); err != nil {
return err
}
defer os.Remove(extensionsRepo)
Expand Down Expand Up @@ -2069,71 +2011,3 @@ func (dn *CoreOSDaemon) applyLayeredOSChanges(mcDiff machineConfigDiff, oldConfi
// Apply extensions
return dn.applyExtensions(oldConfig, newConfig)
}

func (dn *CoreOSDaemon) applyLegacyOSChanges(mcDiff machineConfigDiff, oldConfig, newConfig *mcfgv1.MachineConfig) (retErr error) {
var osImageContentDir string
var err error
if mcDiff.osUpdate || mcDiff.extensions || mcDiff.kernelType {

if osImageContentDir, err = ExtractOSImage(newConfig.Spec.OSImageURL); err != nil {
return err
}
// Delete extracted OS image once we are done.
defer os.RemoveAll(osImageContentDir)

if err := addExtensionsRepo(osImageContentDir); err != nil {
return err
}
defer os.Remove(extensionsRepo)
}

// Update OS
if mcDiff.osUpdate {
if err := dn.updateOS(newConfig, osImageContentDir); err != nil {
mcdPivotErr.Inc()
return err
}
if dn.nodeWriter != nil {
dn.nodeWriter.Eventf(corev1.EventTypeNormal, "OSUpgradeApplied", "OS upgrade applied; new MachineConfig (%s) has new OS image (%s)", newConfig.Name, newConfig.Spec.OSImageURL)
}
} else { //nolint:gocritic // The nil check for dn.nodeWriter has nothing to do with an OS update being unavailable.
// An OS upgrade is not available
if dn.nodeWriter != nil {
dn.nodeWriter.Eventf(corev1.EventTypeNormal, "OSUpgradeSkipped", "OS upgrade skipped; new MachineConfig (%s) has same OS image (%s) as old MachineConfig (%s)", newConfig.Name, newConfig.Spec.OSImageURL, oldConfig.Name)
}
}

// if we're here, we've successfully pivoted, or pivoting wasn't necessary, so we reset the error gauge
mcdPivotErr.Set(0)

defer func() {
// Operations performed by rpm-ostree on the booted system are available
// as staged deployment. It gets applied only when we reboot the system.
// In case of an error during any rpm-ostree transaction, removing pending deployment
// should be sufficient to discard any applied changes.
if retErr != nil {
// Print out the error now so that if we fail to cleanup -p, we don't lose it.
klog.Infof("Rolling back applied changes to OS due to error: %v", retErr)
if err := removePendingDeployment(); err != nil {
errs := kubeErrs.NewAggregate([]error{err, retErr})
retErr = fmt.Errorf("error removing staged deployment: %w", errs)
return
}
}
}()

// Apply kargs
if mcDiff.kargs {
if err := dn.updateKernelArguments(oldConfig.Spec.KernelArguments, newConfig.Spec.KernelArguments); err != nil {
return err
}
}

// Switch to real time kernel
if err := dn.switchKernel(oldConfig, newConfig); err != nil {
return err
}

// Apply extensions
return dn.applyExtensions(oldConfig, newConfig)
}

0 comments on commit e91b573

Please sign in to comment.