Skip to content

Commit

Permalink
install: add --copy-network and --network-dir options
Browse files Browse the repository at this point in the history
This will allow us to copy in networking configuration from a specified
location into a predetermined directory inside of `/boot/` of the
installed system (which follows the path of other postprocess steps).
Having this mechanism will allow for a user to interactively configure
networking in the Live ISO environment via `nmtui` and then have those
settings propagate forward into the installed system.

After the files are copied into the directory within `/boot/` a systemd
unit from the initramfs will pick them up on firstboot and propagate
them into the appropriate locations.

Fixes: #205
  • Loading branch information
dustymabe committed Apr 15, 2020
1 parent 89fa9cd commit df06c7b
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 2 deletions.
27 changes: 27 additions & 0 deletions src/cmdline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ pub struct InstallConfig {
pub firstboot_kargs: Option<String>,
pub insecure: bool,
pub preserve_on_error: bool,
pub network_config: Option<String>,
}

pub struct DownloadConfig {
Expand Down Expand Up @@ -136,6 +137,22 @@ pub fn parse_args() -> Result<Config> {
.help("Additional kernel args for the first boot")
.takes_value(true),
)
.arg(
Arg::with_name("copy-network")
.short("n")
.long("copy-network")
.help("Copy network config from install environment"),
)
.arg(
Arg::with_name("network-dir")
.long("network-dir")
.value_name("path")
.default_value("/etc/NetworkManager/system-connections/")
.takes_value(true)
.empty_values(false)
.help("For use with -n.")
.next_line_help(true), // so we can stay under 80 chars
)
// obscure options without short names
.arg(
Arg::with_name("insecure")
Expand Down Expand Up @@ -400,6 +417,15 @@ fn parse_install(matches: &ArgMatches) -> Result<Config> {
// and report it to the user
eprintln!("{}", location);

// If the user requested us to copy networking config by passing
// -n or --copy-network then copy networking config from the
// directory defined by --network-dir.
let network_config = if matches.is_present("copy-network") {
matches.value_of("network-dir").map(String::from)
} else {
None
};

// build configuration
Ok(Config::Install(InstallConfig {
device,
Expand All @@ -409,6 +435,7 @@ fn parse_install(matches: &ArgMatches) -> Result<Config> {
firstboot_kargs: matches.value_of("firstboot-kargs").map(String::from),
insecure: matches.is_present("insecure"),
preserve_on_error: matches.is_present("preserve-on-error"),
network_config,
}))
}

Expand Down
42 changes: 40 additions & 2 deletions src/install.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

use error_chain::{bail, ChainedError};
use nix::mount;
use std::fs::{create_dir_all, read_dir, File, OpenOptions};
use std::fs::{copy as fscopy, create_dir_all, read_dir, File, OpenOptions};
use std::io::{copy, Read, Seek, SeekFrom, Write};
use std::os::unix::fs::FileTypeExt;
use std::path::Path;
Expand Down Expand Up @@ -111,7 +111,11 @@ fn write_disk(
udev_settle()?;

// postprocess
if ignition.is_some() || config.firstboot_kargs.is_some() || config.platform.is_some() {
if ignition.is_some()
|| config.firstboot_kargs.is_some()
|| config.platform.is_some()
|| config.network_config.is_some()
{
let mount = mount_partition_by_label(&config.device, "boot", mount::MsFlags::empty())?;
if let Some(ignition) = ignition {
write_ignition(mount.mountpoint(), ignition)?;
Expand All @@ -122,6 +126,9 @@ fn write_disk(
if let Some(platform) = config.platform.as_ref() {
write_platform(mount.mountpoint(), platform)?;
}
if let Some(network_config) = config.network_config.as_ref() {
copy_network_config(mount.mountpoint(), network_config)?;
}
}

Ok(())
Expand Down Expand Up @@ -233,6 +240,37 @@ fn write_platform(mountpoint: &Path, platform: &str) -> Result<()> {
Ok(())
}

/// Copy networking config if asked to do so
fn copy_network_config(mountpoint: &Path, net_config_src: &str) -> Result<()> {
eprintln!("Copying networking configuration from {}", net_config_src);

// get the path to the destination directory
let net_config_dest = mountpoint.join("coreos-installer-network");

// make the directory if it doesn't exist
create_dir_all(&net_config_dest).chain_err(|| {
format!(
"creating destination networking config directory {}",
net_config_dest.display()
)
})?;

// copy files from source to destination directories
for entry in
read_dir(&net_config_src).chain_err(|| format!("reading directory {}", net_config_src))?
{
let entry = entry.chain_err(|| format!("reading directory {}", net_config_src))?;
let srcpath = entry.path();
let destpath = net_config_dest.join(entry.file_name());
if srcpath.is_file() {
eprintln!("Copying {} to installed system", srcpath.display());
fscopy(&srcpath, &destpath).chain_err(|| "Copying networking config")?;
}
}

Ok(())
}

/// Clear the partition table. For use after a failure.
fn clear_partition_table(dest: &mut File) -> Result<()> {
eprintln!("Clearing partition table");
Expand Down

0 comments on commit df06c7b

Please sign in to comment.