From 9238e0f7325ca46108c709bc8fcf29f650c54e79 Mon Sep 17 00:00:00 2001 From: Joe Doss Date: Wed, 5 Mar 2025 11:39:07 -0600 Subject: [PATCH] "Add support for reading Ignition data out of the vendor-data file. No longer clobber the user-data file." --- docs/release-notes.md | 1 + docs/supported-platforms.md | 2 +- internal/providers/proxmoxve/proxmoxve.go | 45 ++++++++++++++++------- 3 files changed, 34 insertions(+), 14 deletions(-) diff --git a/docs/release-notes.md b/docs/release-notes.md index bbdd85257..dea10afbf 100644 --- a/docs/release-notes.md +++ b/docs/release-notes.md @@ -14,6 +14,7 @@ Starting with this release, ignition-validate binaries are signed with the ### Features - Add Azure blob support for fetching ignition configs +- Add a check for ignition config in vendor-data (proxmoxve) ### Changes diff --git a/docs/supported-platforms.md b/docs/supported-platforms.md index eef319b22..d2434e2ec 100644 --- a/docs/supported-platforms.md +++ b/docs/supported-platforms.md @@ -24,7 +24,7 @@ Ignition is currently supported for the following platforms: * Bare Metal (`metal`) - Use the `ignition.config.url` kernel parameter to provide a URL to the configuration. The URL can use the `http://`, `https://`, `tftp://`, `s3://`, `arn:`, or `gs://` schemes to specify a remote config. * [Nutanix] (`nutanix`) - Ignition will read its configuration from the instance userdata via config drive. Cloud SSH keys are handled separately. * [OpenStack] (`openstack`) - Ignition will read its configuration from the instance userdata via either metadata service or config drive. Cloud SSH keys are handled separately. -* [Proxmox VE] (`proxmoxve`) - Ignition will read its configuration from the instance userdata via config drive. Cloud SSH keys are handled separately. +* [Proxmox VE] (`proxmoxve`) - Ignition will read its configuration from the instance userdata via config drive. If there isn't any valid Ignition configuration in userdata it will check the vendordata next. Cloud SSH keys are handled separately. * [Equinix Metal] (`packet`) - Ignition will read its configuration from the instance userdata. Cloud SSH keys are handled separately. * [IBM Power Systems Virtual Server] (`powervs`) - Ignition will read its configuration from the instance userdata. Cloud SSH keys are handled separately. * [QEMU] (`qemu`) - Ignition will read its configuration from the 'opt/com.coreos/config' key on the QEMU Firmware Configuration Device (available in QEMU 2.4.0 and higher). diff --git a/internal/providers/proxmoxve/proxmoxve.go b/internal/providers/proxmoxve/proxmoxve.go index 490bfe30f..3d27bb6b9 100644 --- a/internal/providers/proxmoxve/proxmoxve.go +++ b/internal/providers/proxmoxve/proxmoxve.go @@ -40,7 +40,9 @@ import ( ) const ( - cidataPath = "/user-data" + ciuserdataPath = "/user-data" + // See https://bugzilla.proxmox.com/show_bug.cgi?id=2429 for more details about vendordata + civendordataPath = "/vendor-data" deviceLabel = "cidata" ) @@ -123,20 +125,37 @@ func fetchConfigFromDevice(logger *log.Logger, ctx context.Context, path string) ) }() - if !fileExists(filepath.Join(mnt, cidataPath)) { - return nil, nil - } + paths := []string{ciuserdataPath, civendordataPath} + header := []byte("#cloud-config\n") - contents, err := os.ReadFile(filepath.Join(mnt, cidataPath)) - if err != nil { - return nil, err - } + for _, path := range paths { + fullPath := filepath.Join(mnt, path) + if !fileExists(fullPath) { + continue + } - header := []byte("#cloud-config\n") - if bytes.HasPrefix(contents, header) { - logger.Debug("config drive (%q) contains a cloud-config configuration, ignoring", path) - return nil, nil + contents, err := os.ReadFile(fullPath) + if err != nil { + // Log the error but continue to next file + logger.Debug("failed to read %q: %v", fullPath, err) + continue + } + + // Skip if it's a cloud-config file + if bytes.HasPrefix(contents, header) { + logger.Debug("config drive (%q) contains a cloud-config configuration, ignoring", fullPath) + continue + } + + // Check if there's actual content in the file + if len(contents) > 0 { + logger.Debug("config drive (%q) contains data", fullPath) + return contents, nil + } + + logger.Debug("config drive (%q) is empty, ignoring", fullPath) } - return contents, nil + // No valid configuration found in any of the files + return nil, nil }