Skip to content

[mic][iso] generate PXE-bootable ISO images.#10595

Merged
gmileka merged 18 commits into
3.0-devfrom
gmileka/mic-iso-pxe-official-pr
Nov 12, 2024
Merged

[mic][iso] generate PXE-bootable ISO images.#10595
gmileka merged 18 commits into
3.0-devfrom
gmileka/mic-iso-pxe-official-pr

Conversation

@gmileka

@gmileka gmileka commented Oct 1, 2024

Copy link
Copy Markdown
Merge Checklist

All boxes should be checked before merging the PR (just tick any boxes which don't apply to this PR)

  • The toolchain has been rebuilt successfully (or no changes were made to it)
  • The toolchain/worker package manifests are up-to-date
  • Any updated packages successfully build (or no packages were changed)
  • Packages depending on static components modified in this PR (Golang, *-static subpackages, etc.) have had their Release tag incremented.
  • Package tests (%check section) have been verified with RUN_CHECK=y for existing SPEC files, or added to new SPEC files
  • All package sources are available
  • cgmanifest files are up-to-date and sorted (./cgmanifest.json, ./toolkit/scripts/toolchain/cgmanifest.json, .github/workflows/cgmanifest.json)
  • LICENSE-MAP files are up-to-date (./LICENSES-AND-NOTICES/SPECS/data/licenses.json, ./LICENSES-AND-NOTICES/SPECS/LICENSES-MAP.md, ./LICENSES-AND-NOTICES/SPECS/LICENSE-EXCEPTIONS.PHOTON)
  • All source files have up-to-date hashes in the *.signatures.json files
  • sudo make go-tidy-all and sudo make go-test-coverage pass
  • Documentation has been updated to match any changes to the build system
  • Ready to merge

Summary

This change enables the Azures Linux Image Customizer to generate liveos ISO images that are 'PXE-ready'. To be 'PXE-ready', the user should be able to take the generated artifacts, copy them to a PXE server, and is then able to boot PXE clients - without any modifications to any of the artifacts.

To enable such experience, the work involves:

  1. Ensure that Dracut's livenet module (which supports downloading liveos ISOs) works correctly.
  2. Include the livenet module in the MIC generated liveos ISO images.
  3. Generate a grub.cfg with kernel parameters that correctly configures Dracut's livenet module.
  4. Generate a folder with OS artifacts that are directly copy-able to the PXE server for deployment.

The first requirement is broken in Dracut 102 and earlier versions. The fix is covered by this PR: Enable Dracut's livenet rootfs handling when systemd-networkd is in use..

The other three requirements are implemented in this PR.

The changes include:

  • interface:
    • configuration: new configuration to specify the download url for the iso.
    • command-line: new parameter to export the iso image contents into a folder for easier deployment unto a pxe server.
  • implementation:
    • implemented the above interface changes.
    • extended the set of parameters that must be saved between runs to include the new pxe parameters.
    • updated the code to emit a pxe grub.cfg and a pxe dracut config.
Regression Risk

Small.

This is a new code path enabling a new flow. However, there's some overlap with saving MIC internal state between runs.

Change Log
  • See commits.
Does this affect the toolchain?
  • no
Associated issues
  • 9739
Links to CVEs
  • n/a
Test Methodology

Unit Tests

  • Ran MIC liveos ISO tests (tests include coverage for new scenario).

Functional Tests

  • Deploy a PXE server on the network.
  • Use MIC to generate a liveos iso (vhdx->iso) and specify the new --output-pxe-artifacts-dir parameter.
    • Attach the iso to a hyper-v VM
      • Verify the VM boots, and the user can log-in.
    • Deploy the iso artifacts to a PXE server and boot a PXE client on the same network.
      • Verify the PXE client boots, and that the user can log-in.
  • Use MIC to generate a liveos iso (iso->iso) and specify the new --output-pxe-artifacts-dir parameter.
    • Attach the iso to a hyper-v VM
      • Verify the VM boots, and the user can log-in.
    • Deploy the iso artifacts to a PXE server and boot a PXE client on the same network.
      • Verify the PXE client boots, and that the user can log-in.
      • Verify user settings from the first run (vhdx-iso) have been retained.

@gmileka gmileka force-pushed the gmileka/mic-iso-pxe-official-pr branch from f2825b8 to d6fd3b9 Compare October 2, 2024 00:22
@gmileka gmileka marked this pull request as ready for review October 2, 2024 19:35
@gmileka gmileka requested review from a team as code owners October 2, 2024 19:35
Comment thread SPECS/dracut/add-livenet-download-service.patch Outdated
Comment thread SPECS/dracut/add-livenet-download-service.patch Outdated
Comment thread toolkit/tools/imagecustomizer/docs/cli.md Outdated
Comment thread toolkit/tools/imagecustomizer/docs/configuration.md Outdated
Comment thread toolkit/tools/imagecustomizer/docs/samples/deploy-pxe-artifacts.sh Outdated
Comment thread toolkit/tools/imagecustomizer/docs/samples/deploy-pxe-artifacts.sh Outdated
Comment thread toolkit/tools/imagecustomizer/docs/samples/deploy-pxe-artifacts.sh Outdated
Comment thread toolkit/tools/pkg/imagecustomizerlib/liveosisobuilder.go Outdated
Comment thread toolkit/tools/pkg/imagecustomizerlib/liveosisobuilder.go Outdated
Comment thread toolkit/tools/pkg/imagecustomizerlib/liveosisobuilder.go Outdated
Comment thread toolkit/tools/pkg/imagecustomizerlib/liveosisobuilder.go Outdated
Comment thread toolkit/tools/imagecustomizer/docs/configuration.md Outdated
Comment thread SPECS/dracut/add-livenet-download-service.patch Outdated
@gmileka gmileka force-pushed the gmileka/mic-iso-pxe-official-pr branch from e5ee6be to 39eea29 Compare October 23, 2024 00:58
@gmileka gmileka requested a review from a team as a code owner October 23, 2024 00:58
@gmileka gmileka force-pushed the gmileka/mic-iso-pxe-official-pr branch from 0fd9990 to c9ba796 Compare October 29, 2024 20:41
@gmileka gmileka force-pushed the gmileka/mic-iso-pxe-official-pr branch from 2651c55 to d382736 Compare November 1, 2024 00:43
Comment thread toolkit/tools/imagecustomizer/main.go Outdated
Comment thread toolkit/tools/imagecustomizer/docs/configuration.md Outdated
Comment thread toolkit/tools/imagecustomizer/docs/configuration.md Outdated
Comment thread toolkit/tools/imagecustomizer/docs/configuration.md Outdated
Comment thread toolkit/tools/imagecustomizer/docs/configuration.md Outdated
// Extrack package distro and version
distroName := ""
distroVersion := uint32(0)
if strings.HasPrefix(parts[1], azureLinuxPackagePrefix) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

The dracut package version check you will need to do for each distro/distro-version combination will likely need to be different. So, it probably isn't worth splitting the distro and distro-version.

For example, have a map of distro+version -> minimum supported dracut version.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

My thinking is that the generic pkg level api, here in customizepackages, is agnostic of how the version information will be used, and hence we should centralize the code to break down and let higher level code decide how to use the data.

For this PR, there is the verifyDracutPXESupport function using this version information. This is where we could implement the map as the need arises. For now, we have only 3.0 to support, and the version check is relatively simple. If in the future we run into a scenario where the pxe version check needs to be different for each major azl release, then we can introduce map.

Comment thread toolkit/tools/pkg/imagecustomizerlib/liveosisobuilder_test.go Outdated
Comment thread toolkit/tools/pkg/imagecustomizerlib/liveosisobuilder.go Outdated
Comment thread toolkit/tools/pkg/imagecustomizerlib/liveosisobuilder.go Outdated
}

type OSSavedConfigs struct {
DracutPackageInfo DracutPackageInformation `yaml:"dracutPackage"`

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Within the initramfs file, the /etc/os-release file contains both the distro + version and the dracut version. Our dracut.spec file even patches the package release version into dracut.

For example:

NAME="Microsoft Azure Linux"
ID=azurelinux
VERSION_ID="3.0"
ANSI_COLOR="1;34"
HOME_URL="https://aka.ms/azurelinux"
BUG_REPORT_URL="https://aka.ms/azurelinux"
SUPPORT_URL="https://aka.ms/azurelinux"
VERSION="3.0.20240824 dracut-102-4.azl3"
PRETTY_NAME="Microsoft Azure Linux 3.0 dracut-102-4.azl3 (Initramfs)"
DRACUT_VERSION="102-4.azl3"

So, if you extracted that file, we wouldn't need to carry around the dracut version in the save config file.

This would also make the code more distro independent.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Interesting - just tried it. I will need to unpack the initrd, parse the os-release file, and then clean-up.

The current implementation captures the dracut version by running rpm while we have the rootfs expanded, and then later the information is parsed along with the rest of the saved configs.

The caching allows us to modify an iso image faster than unpacking initrd. The code in mic will not be simpler because of the additional logic (while we already have logic for saving/loading configs - so, minimal cost there).

I think your point about being distro-independent refers to the fact that we won't depend on running rpm - correct? But when we support other distros, we'd probably abstract the package manager and the code will be the same at a higher level.

I'm leaning towards using the cached copy instead of re-extracting it every run.

Comment thread toolkit/tools/pkg/imagecustomizerlib/liveosisobuilder.go Outdated
Comment thread toolkit/tools/pkg/imagecustomizerlib/liveosisobuilder.go Outdated
// If the specified URL is not a full path to an iso, append the generated
// iso file name to it.
if pxeIsoImageFileUrl == "" {
pxeIsoImageFileUrl, err = url.JoinPath(pxeIsoImageBaseUrl, outputImageBase+".iso")

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

I believe this is only correct because LiveOSIsoBuilder.createIsoImage() / isomakerlib appends .iso to the filename. This makes verifying code correctness difficult. I also don't like the fact that the output filename could be different than the one the user provided if the user doesn't use the .iso extension.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

And a minimum, you should at least have a helper function within this file that handles adding ".iso". Currently, there are 3 separate locations within this file that does this.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Technically, I agree that we should honor the user specified output image name - though it'd be strange if the user wants an iso image that does not have an iso extension. I think, in practice, this will be very rare.

@gmileka gmileka force-pushed the gmileka/mic-iso-pxe-official-pr branch from 3a85100 to 230c9f0 Compare November 5, 2024 23:49
@gmileka gmileka force-pushed the gmileka/mic-iso-pxe-official-pr branch from 7e82fb3 to 765122b Compare November 6, 2024 01:47
@gmileka gmileka merged commit 8245797 into 3.0-dev Nov 12, 2024
@gmileka gmileka deleted the gmileka/mic-iso-pxe-official-pr branch November 12, 2024 20:04
durgajagadeesh pushed a commit to durgajagadeesh/azurelinux_djpalli that referenced this pull request Dec 31, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants