in metalos/metalctl/src/generator.rs [266:361]
fn generator_maybe_err(cmdline: MetalosCmdline, log: Logger, opts: Opts) -> Result<BootMode> {
let boot_mode = detect_mode(&cmdline).context("failed to detect boot mode")?;
info!(log, "Booting with mode: {:?}", boot_mode);
// use the mac address in the kernel command line, otherwise try to infer it
// using crate::net_utils::get_mac()
let mac_address: Option<String> = match cmdline.mac_address {
Some(mac) => Some(mac),
None => match get_mac() {
Ok(m) => Some(m),
Err(error) => {
error!(log, "Skipping network dropin. Error was: {}", error);
None
}
},
};
match &boot_mode {
BootMode::MetalOSExisting => {
let boot_info_result = metalos_existing_boot_info(
cmdline.root,
cmdline
.host_config_uri
.context("host-config-uri must be provided for metalos boots")?,
mac_address,
)
.context("Failed to build normal metalos info")?;
materialize_boot_info(
log,
&opts.normal_dir,
&opts.environment_dir,
&opts.network_unit_dir,
boot_info_result.env,
boot_info_result.extra_deps,
boot_info_result.mount_unit,
boot_info_result.network_unit_dropin,
)
}
BootMode::MetalOSReimage => {
let boot_info_result = metalos_reimage_boot_info(
cmdline.root,
cmdline
.host_config_uri
.context("host-config-uri must be provided for metalos boots")?,
cmdline
.root_disk_package
.context("Root disk package must be provided for metalos reimage boots")?,
mac_address,
)
.context("Failed to build normal metalos info")?;
materialize_boot_info(
log,
&opts.normal_dir,
&opts.environment_dir,
&opts.network_unit_dir,
boot_info_result.env,
boot_info_result.extra_deps,
boot_info_result.mount_unit,
boot_info_result.network_unit_dropin,
)
}
BootMode::Legacy => {
let boot_info_result = legacy_boot_info(cmdline.root, mac_address)
.context("failed to build legacy info")?;
materialize_boot_info(
log,
&opts.normal_dir,
&opts.environment_dir,
&opts.network_unit_dir,
boot_info_result.env,
boot_info_result.extra_deps,
boot_info_result.mount_unit,
boot_info_result.network_unit_dropin,
)
}
}
.context("Failed to materialize_boot_info")?;
// IMPORTANT: this MUST be the last thing that the generator does, otherwise
// any bugs in the generator can be masked and cause future hard-to-diagnose
// failures
let default_target_path = opts.early_dir.join("default.target");
match std::fs::remove_file(&default_target_path) {
// NotFound error is Ok, others are not
Err(err) if err.kind() == std::io::ErrorKind::NotFound => Ok(()),
x => x,
}
.context("while removing original default.target")?;
symlink("/usr/lib/systemd/system/initrd.target", default_target_path)
.context("while changing default target to initrd.target")?;
Ok(boot_mode)
}