-
Notifications
You must be signed in to change notification settings - Fork 128
feat(azure): Add Azure Ignition fragment generation #1264
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 2 commits
54a726c
68762e9
0b85a44
3a627b4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| [Unit] | ||
| Description=Afterburn Ignition Config Fragment Generator | ||
| Documentation=https://coreos.github.io/afterburn/ | ||
|
|
||
| # Only run on platforms that support ignition fragment generation. | ||
| ConditionKernelCommandLine=|ignition.platform.id=azure | ||
|
|
||
| # Run after networking is available (needed for the Azure IMDS call). Use | ||
| # network.target (not network-online.target) to match ignition-fetch.service | ||
| # and avoid stalling on multi-NIC DHCP; IMDS is link-local and afterburn | ||
| # has its own retry logic. | ||
| # | ||
| # Run between fetch and disks so writes don't race the fetch stage's parse | ||
| # of base.platform.d (Ignition re-reads it every stage; applied at files). | ||
| After=network.target | ||
| After=ignition-fetch.service | ||
| Before=ignition-disks.service | ||
|
|
||
| OnFailure=emergency.target | ||
| OnFailureJobMode=isolate | ||
|
|
||
| [Service] | ||
| ExecStartPre=/usr/bin/mkdir -p /etc/ignition/base.platform.d/azure | ||
| ExecStart=/usr/bin/afterburn render-ignition --cmdline --render-ignition-dir /etc/ignition/base.platform.d/azure/ --platform-extensions | ||
| Type=oneshot | ||
| RemainAfterExit=yes | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,78 @@ | ||
| //! `render-ignition` CLI sub-command. | ||
| //! | ||
| //! Generates per-feature Ignition config fragment files in an output directory. | ||
| //! Each enabled feature writes its own `.ign` file; Ignition merges them | ||
| //! natively from `base.platform.d/<platform>/` under a system config directory | ||
| //! such as `/etc/ignition`. | ||
|
|
||
| use anyhow::{bail, Context, Result}; | ||
| use clap::{ArgGroup, Parser}; | ||
|
|
||
| /// Render Ignition config fragments from cloud provider metadata | ||
| #[derive(Debug, Parser)] | ||
| #[command(group(ArgGroup::new("provider-group").args(["cmdline", "provider"]).required(true)))] | ||
| pub struct CliRenderIgnition { | ||
| /// The name of the cloud provider | ||
| #[arg(long, value_name = "name")] | ||
| provider: Option<String>, | ||
|
peytonr18 marked this conversation as resolved.
|
||
| /// Read the cloud provider from the kernel cmdline | ||
| #[arg(long)] | ||
| cmdline: bool, | ||
| /// Directory to write Ignition config fragment files into | ||
| #[arg(long = "render-ignition-dir", value_name = "path")] | ||
| render_ignition_dir: String, | ||
| /// Include hostname in a fragment file | ||
| #[arg(long)] | ||
| hostname: bool, | ||
| /// Include platform user and SSH keys in a fragment file | ||
| #[arg(long)] | ||
| platform_user: bool, | ||
| /// Enable all platform extensions (implies --hostname --platform-user) | ||
|
Rolv-Apneseth marked this conversation as resolved.
Outdated
|
||
| #[arg(long)] | ||
| platform_extensions: bool, | ||
| } | ||
|
|
||
| impl CliRenderIgnition { | ||
| const SUPPORTED_PROVIDERS: &[&str] = &["azure"]; | ||
|
|
||
| pub(crate) fn run(self) -> Result<()> { | ||
| let provider_id = super::get_provider(self.provider.as_deref())?; | ||
|
|
||
| if !Self::SUPPORTED_PROVIDERS.contains(&provider_id.as_str()) { | ||
| bail!( | ||
| "render-ignition is only supported for providers {:?}, got '{}'", | ||
| Self::SUPPORTED_PROVIDERS, | ||
| provider_id, | ||
| ); | ||
| } | ||
|
|
||
| let hostname = self.hostname || self.platform_extensions; | ||
| let platform_user = self.platform_user || self.platform_extensions; | ||
|
|
||
| if !hostname && !platform_user { | ||
| slog_scope::warn!("render-ignition: no features specified"); | ||
| return Ok(()); | ||
| } | ||
|
|
||
| let metadata = crate::metadata::fetch_metadata(&provider_id) | ||
| .context("fetching metadata from provider")?; | ||
|
|
||
| if hostname { | ||
| crate::providers::microsoft::azure::config::generate_hostname_fragment( | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this is azure-specific call in cli code. this should be generic to provider
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Quick design question: after our offline discussion, An alternative would be to move that provider→fragment orchestration onto the // src/providers/mod.rs
fn write_hostname_ignition_fragment(&self, output_dir: &str) -> Result<()> {
let Some(hostname) = self.hostname()? else { return Ok(()); };
let path = Path::new(output_dir).join("hostname.ign");
IgnitionConfig::hostname_fragment(&hostname).write_to(&path)
}
fn write_user_ignition_fragment(&self, output_dir: &str) -> Result<()> {
// admin_username / ssh_keys / admin_password_hash -> IgnitionConfig::user_fragment(..).write_to(..)
}Do you think the trait-default-method approach would be cleaner/preferred here, or is the current split fine? I'm happy to switch the approach if the trait method seems better - it's a small change either way.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think defaults defined in the trait would be preferable but I would like to hear @prestist's thoughts on the subject |
||
| metadata.as_ref(), | ||
| &self.render_ignition_dir, | ||
| ) | ||
| .context("generating hostname ignition fragment")?; | ||
| } | ||
|
|
||
| if platform_user { | ||
| crate::providers::microsoft::azure::config::generate_user_fragment( | ||
| metadata.as_ref(), | ||
| &self.render_ignition_dir, | ||
| ) | ||
| .context("generating platform-user ignition fragment")?; | ||
| } | ||
|
|
||
| Ok(()) | ||
| } | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.