Skip to content

Conversation

pawanpinjarkar
Copy link
Contributor

Description

This PR enhances the way kernel arguments (kargs) are handled in RHCOS ISOs by updating both isolinux.cfg and coreos/kargs.jso files during minimal ISO generation.

Key changes:

  • fixIsolinuxConfig now returns the modified config content for reuse instead of writing blindly to disk.

  • Added fixKargsConfig, which extracts the kernel args starting with rw from isolinux.cfg and updates the embedded coreos/kargs.jso JSON file with correct kernel arguments and offset values.

  • Introduced helper functions extractBootArgs and buildKargsContent to support safe, consistent parsing and rewriting of kernel args.

  • Updated test data to include sample kargs.jso.

  • Extended test coverage to validate both isolinux.cfg and kargs.jso updates in cases with and without the nmstate disk image.

This improves consistency across bootloaders (isolinux and grub), avoids stale coreos.liveiso entries, and ensures correct injection of dynamic rootfs URLs and initrds, especially when including nmstate or other additional initrd images.

How was this code tested?

Unit Tests: Added new tests in rhcos_test.go to validate that:

  • fixIsolinuxConfig correctly removes coreos.liveiso, adds rw, and appends appropriate initrd paths.

  • fixKargsConfig correctly parses the kernel args from isolinux.cfg, modifies the kargs.jso file with correct offsets, and embeds updated args.

Assignees

/cc @
/cc @

Links

Checklist

  • Title and description added to both, commit and PR
  • Relevant issues have been associated
  • Reviewers have been listed
  • This change does not require a documentation update (docstring, docs, README, etc)
  • Does this change include unit tests (note that code changes require unit tests)

…RUB and ISOLINUX config edits

Replaced repetitive editFile logic with reusable helper functions:
- `replacePatternInFile`: performs regex replacement and returns the updated file content.
- `saveFile`: writes content to file with secure permissions (0600).

Updated `fixGrubConfig` and `fixIsolinuxConfig` to use these helpers for:
- Adding coreos.live.rootfs_url
- Removing coreos.liveiso
- Modifying initrd lines with optional nmstate ramdisk

This improves readability, testability, and maintainability of config mutation logic during ISO generation.
@openshift-ci openshift-ci bot added the size/L Denotes a PR that changes 100-499 lines, ignoring generated files. label Aug 4, 2025
@openshift-ci openshift-ci bot requested review from adriengentil and avishayt August 4, 2025 14:08
Copy link

openshift-ci bot commented Aug 4, 2025

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: pawanpinjarkar
Once this PR has been reviewed and has the lgtm label, please assign romfreiman for approval. For more information see the Code Review Process.

The full list of commands accepted by this bot can be found here.

Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@pawanpinjarkar
Copy link
Contributor Author

/cc @bfournie @zaneb @andfasano

@openshift-ci openshift-ci bot requested review from andfasano, bfournie and zaneb August 4, 2025 14:09
…port

- Refactored fixIsolinuxConfig to return modified content for reuse.
- Added fixKargsConfig to generate and update kargs.jso with correct kernel args and offset.
- Introduced utility functions for extracting boot args and rebuilding kargs.jso.
- Enhanced test coverage for both isolinux and kargs config logic.
- Updated test data to reflect new kernel argument structure
@pawanpinjarkar pawanpinjarkar changed the title Fix kargs OCPBUGS-43501: coreos-installer iso kargs show broken when using minimal ISO Aug 4, 2025
@openshift-ci-robot openshift-ci-robot added jira/severity-moderate Referenced Jira bug's severity is moderate for the branch this PR is targeting. jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. jira/invalid-bug Indicates that a referenced Jira bug is invalid for the branch this PR is targeting. labels Aug 4, 2025
@openshift-ci-robot
Copy link

@pawanpinjarkar: This pull request references Jira Issue OCPBUGS-43501, which is invalid:

  • expected the bug to target the "4.20.0" version, but no target version was set

Comment /jira refresh to re-evaluate validity if changes to the Jira bug are made, or edit the title of this pull request to link to a different bug.

The bug has been updated to refer to the pull request using the external bug tracker.

In response to this:

Description

This PR enhances the way kernel arguments (kargs) are handled in RHCOS ISOs by updating both isolinux.cfg and coreos/kargs.jso files during minimal ISO generation.

Key changes:

  • fixIsolinuxConfig now returns the modified config content for reuse instead of writing blindly to disk.

  • Added fixKargsConfig, which extracts the kernel args starting with rw from isolinux.cfg and updates the embedded coreos/kargs.jso JSON file with correct kernel arguments and offset values.

  • Introduced helper functions extractBootArgs and buildKargsContent to support safe, consistent parsing and rewriting of kernel args.

  • Updated test data to include sample kargs.jso.

  • Extended test coverage to validate both isolinux.cfg and kargs.jso updates in cases with and without the nmstate disk image.

This improves consistency across bootloaders (isolinux and grub), avoids stale coreos.liveiso entries, and ensures correct injection of dynamic rootfs URLs and initrds, especially when including nmstate or other additional initrd images.

How was this code tested?

Unit Tests: Added new tests in rhcos_test.go to validate that:

  • fixIsolinuxConfig correctly removes coreos.liveiso, adds rw, and appends appropriate initrd paths.

  • fixKargsConfig correctly parses the kernel args from isolinux.cfg, modifies the kargs.jso file with correct offsets, and embeds updated args.

Assignees

/cc @
/cc @

Links

Checklist

  • Title and description added to both, commit and PR
  • Relevant issues have been associated
  • Reviewers have been listed
  • This change does not require a documentation update (docstring, docs, README, etc)
  • Does this change include unit tests (note that code changes require unit tests)

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

@pawanpinjarkar
Copy link
Contributor Author

/jira refresh

@openshift-ci-robot openshift-ci-robot added jira/valid-bug Indicates that a referenced Jira bug is valid for the branch this PR is targeting. and removed jira/invalid-bug Indicates that a referenced Jira bug is invalid for the branch this PR is targeting. labels Aug 4, 2025
@openshift-ci-robot
Copy link

@pawanpinjarkar: This pull request references Jira Issue OCPBUGS-43501, which is valid. The bug has been moved to the POST state.

3 validation(s) were run on this bug
  • bug is open, matching expected state (open)
  • bug target version (4.20.0) matches configured target version for branch (4.20.0)
  • bug is in the state ASSIGNED, which is one of the valid states (NEW, ASSIGNED, POST)

Requesting review from QA contact:
/cc @mhanss

In response to this:

/jira refresh

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

@openshift-ci openshift-ci bot requested a review from mhanss August 4, 2025 17:52
@pawanpinjarkar
Copy link
Contributor Author

/cherrypick release-4.19, release-4.18, release-4.17, release-4.16

@openshift-cherrypick-robot

@pawanpinjarkar: once the present PR merges, I will cherry-pick it on top of release-4.19, in a new PR and assign it to you.

In response to this:

/cherrypick release-4.19, release-4.18, release-4.17, release-4.16

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository.

Copy link

openshift-ci bot commented Aug 4, 2025

@pawanpinjarkar: The following test failed, say /retest to rerun all failed tests or /retest-required to rerun all mandatory failed tests:

Test name Commit Details Required Rerun command
ci/prow/edge-test 83daebe link true /test edge-test

Full PR test history. Your PR dashboard.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. I understand the commands that are listed here.

Copy link
Member

@carbonin carbonin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a bit strange. Generally I'm not sure why this is happening for only one of the boot configs, I don't know where the original offset numbers are coming from and it seems like there's a lot of unnecessary refactoring going on.

@@ -18,6 +20,16 @@ const (
MinimalVersionForNmstatectl = "4.18.0-ec.0"
)

type FileEntry struct {
Offset int `json:"offset"`
Path string `json:"path"`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are "end" and "pad" just not needed? Maybe add them anyway just for completeness?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had them added initially, its fair, I will add it back again

Path string `json:"path"`
}

type Config struct {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we name this more specifically? This is kargs-specific, right?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

right, will do

@@ -72,6 +93,7 @@ func createTestFiles(volumeID string) (string, string) {
Expect(os.WriteFile(filepath.Join(filesDir, "images/pxeboot/rootfs.img"), []byte("this is rootfs"), 0600)).To(Succeed())
Expect(os.WriteFile(filepath.Join(filesDir, "EFI/redhat/grub.cfg"), []byte(testGrubConfig), 0600)).To(Succeed())
Expect(os.WriteFile(filepath.Join(filesDir, "isolinux/isolinux.cfg"), []byte(testISOLinuxConfig), 0600)).To(Succeed())
Expect(os.WriteFile(filepath.Join(filesDir, "coreos/kargs.jso"), []byte(testKargsConfig), 0600)).To(Succeed())
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Expect(os.WriteFile(filepath.Join(filesDir, "coreos/kargs.jso"), []byte(testKargsConfig), 0600)).To(Succeed())
Expect(os.WriteFile(filepath.Join(filesDir, "coreos/kargs.json"), []byte(testKargsConfig), 0600)).To(Succeed())

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The filename extension in reality is limited just to 3 chars hence .jso

if err != nil {
return err
}
offset := 1903
if includeNmstateRamDisk {
offset = 1923
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where is this number coming from?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The offset was manually calculated during the dev work with the command such as dd if-isolinux.cfg bs=1 skip 1903 when the includeNmstateRamDisk was not included and it was coming to be 1923 when the includeNmstateRamDisk was included.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this the same for every ISO version? I would expect this to vary.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we knew what the grub config file looked like in advance, we could just write the whole file out. We're doing all the replace stuff because we need to be robust against changes in coreos.

I think we need to count the number of characters we're adding/removing and where, then update the offsets/size as appropriate.

log.WithError(err).Warnf("Failed to edit isolinux config")
return err
}
if err := fixKargsConfig(extractDir, contentWithRamDiskPath, includeNmstateRamDisk); err != nil {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why does this only apply for isolinux and not grub?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In isolinux.cfg the offset moves (due to adding the ramdisk images at the beginning of the same line.
In grub.cfg the offset stays the same because the line specifying the initrd images currently appears after the one that specifies the kargs.

if err != nil {
return err
}
if err = saveFile(foundGrubPath, grubFileContent); err != nil {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why save then edit and save again? Couldn't this just be removed?

}

// saveFile writes the given content to the specified file with 0600 permissions.
func saveFile(fileName, content string) error {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function doesn't offer any benefit over just calling os.WriteFile directly. Just deduplicating the permissions hardly seems worth it.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've noticed that AIs love to do this kind of stuff.

}

return nil
}

func fixIsolinuxConfig(rootFSURL, extractDir string, includeNmstateRamDisk bool) error {
func fixIsolinuxConfig(rootFSURL, extractDir string, includeNmstateRamDisk bool) (string, error) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of returning the content as a side-effect, could we leave this unchanged then read the file we need after we call the original function?

// Extract the line content after "append "
kernelArgs := strings.TrimPrefix(trimmed, "append ")
// Find " rw " (with spaces to avoid partial matches)
index := strings.Index(kernelArgs, " rw ")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No reason to think that rw will always be the first arg either.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
jira/severity-moderate Referenced Jira bug's severity is moderate for the branch this PR is targeting. jira/valid-bug Indicates that a referenced Jira bug is valid for the branch this PR is targeting. jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. size/L Denotes a PR that changes 100-499 lines, ignoring generated files.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants