Skip to content

Commit

Permalink
install: add --copy-network-config option
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 14, 2020
1 parent 89fa9cd commit 97f4560
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 2 deletions.
20 changes: 20 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,15 @@ pub fn parse_args() -> Result<Config> {
.help("Additional kernel args for the first boot")
.takes_value(true),
)
.arg(
Arg::with_name("copy-network-config")
.short("n")
.long("copy-network-config")
.value_name("path")
.default_value("/etc/NetworkManager/system-connections/")
.takes_value(true)
.help("Optionally copy the network config from <path> in the installer environment"),
)
// obscure options without short names
.arg(
Arg::with_name("insecure")
Expand Down Expand Up @@ -400,6 +410,15 @@ fn parse_install(matches: &ArgMatches) -> Result<Config> {
// and report it to the user
eprintln!("{}", location);

// We want to only copy networking configs in the user requested it by passing
// -n or --copy-network-config. We can determine this by checking the number
// of occurrences. If > 0 the user did specify the option.
let network_config = if matches.occurrences_of("copy-network-config") > 0 {
matches.value_of("copy-network-config").map(String::from)
} else {
None
};

// build configuration
Ok(Config::Install(InstallConfig {
device,
Expand All @@ -409,6 +428,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
54 changes: 52 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::{create_dir_all, copy as fscopy, read_dir, remove_file, 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,7 @@ 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 +122,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 +236,53 @@ 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 mut net_config_dest = mountpoint.to_path_buf();
net_config_dest.push("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()
)
})?;

// if the directory has files in it then clear them out
for entry in read_dir(&net_config_dest)
.chain_err(|| format!("reading directory {}", net_config_dest.display()))?
{
let entry = entry
.chain_err(|| format!("reading directory {}", net_config_dest.display()))?;
if entry.path().is_file() {
eprintln!("Removing file {}", entry.path().display());
remove_file(entry.path()).
chain_err(|| format!("removing {}", entry.path().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 97f4560

Please sign in to comment.