Azure / azure-init

A minimal provisioning agent designed for Azure Linux VMs.
MIT License
7 stars 10 forks source link

[BUG] media::get_environment attempts to locate a non-existent CDROM device on AzureLinux #99

Open SeanDougherty opened 4 days ago

SeanDougherty commented 4 days ago

Description

When testing #92 on Azure Linux 3.0, azure-init encounters an issue attempting to retrieve block devices using media::get_environment(). This causes azure-init to report an error and exit pre-maturely.

Impact

This is part of work to get azure-init supported on Azure Linux 3.0 (as well as many other distros)

Environment and steps to reproduce

  1. Set-up:

Boot an Azure Linux 3.0 VM, if you need an image, please reach out.

  1. Action(s):

    tdnf install libudev-devel git -y git clone https://github.com/SeanDougherty/azure-init.git cd azure-init git checkout azl cargo build --all ./target/debug/azure-init

  1. Error: Unable to get list of block devices

    Expected behavior

    Azure-init can get a mountable device for its use.

Additional information

I explored more in my branch, and I can see that there are devices available, they just might not be CDROM devices. (See photo)

image

For reference, this JSON is the configuration file used by AzL build tools to compose the image. You can see the devices enumerated under Disks:.

dongsupark commented 3 days ago

Thanks for the bug report.

Azure provides initial provisioning data, ovf-env.xml, as either via UDF/iso9660 device or an IMDS endpoint. The issue is that azure-init currently only supports the local device as source, not IMDS.

We should first check for a local mounted device, then fall back to fetching from IMDS. For example, see cloud-init, or ignition. I think cloud-init code there is too complicated, so would rather recommend the ignition approach.

anhvoms commented 3 days ago

Thanks for the bug report.

Azure provides initial provisioning data, ovf-env.xml, as either via UDF/iso9660 device or an IMDS endpoint. The issue is that azure-init currently only supports the local device as source, not IMDS.

We should first check for a local mounted device, then fall back to fetching from IMDS. For example, see cloud-init, or ignition. I think cloud-init code there is too complicated, so would rather recommend the ignition approach.

Up until PR #79 and #84 azure-init was ok without the mounted media because it would check IMDS first, then fall back to the media. I might be wrong as I'm not a Rust expert but #84 perhaps forced the error (via the use of question mark operator) and as such any environment without the local media would start failing.

The approach used by azure-init and Ignition favors IMDS over mounted media, which is ok if the customer does not use custom-data (azure-init doesn't handle user-data/custom-data to begin with). If the customer users custom-data, Ignition will miss the custom-data in the mounted media I believe (most Azure customers use custom-data and not user-data)

dongsupark commented 3 days ago

Up until PR #79 and #84 azure-init was ok without the mounted media because it would check IMDS first, then fall back to the media. I might be wrong as I'm not a Rust expert but #84 perhaps forced the error (via the use of question mark operator) and as such any environment without the local media would start failing.

Oh, good point, thanks. We already fetch data using imds::query. I misunderstood that.

Yeah, I think what happend was actually until prior #79, commit 2c5cbfd0f8a6, if password auth is disabled, the parse_ovf_env was not even called. We changed the behavior in #84, commit 001dce28f8b7, so that mount_parse_ovf_env is now called in any case. That's why a missing block device started failing immediately.

Another big hidden issue here is, from the beginning until now, imds::query()? leads to an immediate failure. We should change the error handling to make it fall back to probing block devices. And it should skip doing block devices when it successfully got IMDS data.

The approach used by azure-init and Ignition favors IMDS over mounted media, which is ok if the customer does not use custom-data (azure-init doesn't handle user-data/custom-data to begin with). If the customer users custom-data, Ignition will miss the custom-data in the mounted media I believe (most Azure customers use custom-data and not user-data)

I am ok with keeping the current behavior for now.