Skip to content

Commit

Permalink
providers: setup network kernel arguments in initrd
Browse files Browse the repository at this point in the history
This adds initial/experimental support for providing supplemental
network kernel arguments in the initrd.
It is meant to support environment where custom network kargs may
be provided via a back-channel.
Such arguments are only retrieved and applied on first boot, and
their format is defined by dracut [0].
The feature is currently reachable as a dedicated subcommand,
but this does not contain any platform-specific implementation.

[0] https://mirrors.edge.kernel.org/pub/linux/utils/boot/dracut/dracut.html#_network
  • Loading branch information
lucab committed Apr 28, 2020
1 parent 6995f76 commit 01b0a9e
Show file tree
Hide file tree
Showing 9 changed files with 331 additions and 77 deletions.
20 changes: 20 additions & 0 deletions dracut/30afterburn/afterburn-network-kargs.service
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
[Unit]
Description=Afterburn Initrd Setup Network Kernel Arguments

# This service may produce additional kargs fragments,
# which are then consumed by dracut-cmdline(8).
DefaultDependencies=no
Before=dracut-cmdline.service
Before=ignition-fetch.service
After=systemd-journald.socket

OnFailure=emergency.target
OnFailureJobMode=isolate

[Service]
Environment=AFTERBURN_OPT_PROVIDER=--cmdline
# AFTERBURN_NETWORK_KARGS_DEFAULT must be set externally by distributions.
# If unset, variable expansion results in a missing argument and service
# hard-failure, on purpose.
ExecStart=/usr/bin/afterburn exp rd-network-kargs ${AFTERBURN_OPT_PROVIDER} --default-value $AFTERBURN_NETWORK_KARGS_DEFAULT
Type=oneshot
7 changes: 5 additions & 2 deletions dracut/30afterburn/module-setup.sh
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,12 @@ install() {
inst_simple "$moddir/afterburn-hostname.service" \
"$systemdutildir/system/afterburn-hostname.service"

# We want the afterburn-hostname to be firstboot only, so Ignition-provided
# hostname changes do not get overwritten on subsequent boots
inst_simple "$moddir/afterburn-network-kargs.service" \
"$systemdutildir/system/afterburn-network-kargs.service"

# These services are only run once on first-boot, so they piggyback
# on Ignition completion target.
mkdir -p "$initdir/$systemdsystemunitdir/ignition-complete.target.requires"
ln -s "../afterburn-hostname.service" "$initdir/$systemdsystemunitdir/ignition-complete.target.requires/afterburn-hostname.service"
ln -s "../afterburn-network-kargs.service" "$initdir/$systemdsystemunitdir/ignition-complete.target.requires/afterburn-network-kargs.service"
}
74 changes: 74 additions & 0 deletions src/cli/exp.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
//! `exp` CLI sub-command.
use crate::errors::*;
use crate::{initrd, util};
use clap::ArgMatches;
use error_chain::bail;

/// Experimental subcommands.
#[derive(Debug)]
pub enum CliExp {
RdNetworkKargs(CliRdNetworkKargs),
}

impl CliExp {
/// Parse sub-command into configuration.
pub(crate) fn parse(app_matches: &ArgMatches) -> Result<super::CliConfig> {
if app_matches.subcommand_name().is_none() {
bail!("missing subcommand for 'exp'");
}

let cfg = match app_matches.subcommand() {
("rd-network-kargs", Some(matches)) => CliRdNetworkKargs::parse(matches)?,
(x, _) => unreachable!("unrecognized subcommand for 'exp': '{}'", x),
};

Ok(super::CliConfig::Exp(cfg))
}

// Run sub-command.
pub(crate) fn run(&self) -> Result<()> {
match self {
CliExp::RdNetworkKargs(cmd) => cmd.run()?,
};
Ok(())
}
}

/// Sub-command for network kernel arguments.
#[derive(Debug)]
pub struct CliRdNetworkKargs {
platform: String,
default_kargs: String,
}

impl CliRdNetworkKargs {
/// Parse sub-command into configuration.
pub(crate) fn parse(matches: &ArgMatches) -> Result<CliExp> {
let platform = super::parse_provider(matches)?;
let default_kargs = matches
.value_of("default-value")
.ok_or_else(|| "missing network kargs default value")?
.to_string();

let cfg = Self {
platform,
default_kargs,
};
Ok(CliExp::RdNetworkKargs(cfg))
}

/// Run the sub-command.
pub(crate) fn run(&self) -> Result<()> {
if util::has_network_kargs(super::CMDLINE_PATH)? {
slog_scope::warn!("kernel cmdline already specifies network arguments, skipping");
return Ok(());
};

let provider_kargs = initrd::fetch_network_kargs(&self.platform)?;
let kargs = provider_kargs
.as_ref()
.unwrap_or_else(|| &self.default_kargs);
initrd::write_network_kargs(kargs)
}
}
Loading

0 comments on commit 01b0a9e

Please sign in to comment.