From fd6bf73561d2e0e3b0a425e430961651b5851870 Mon Sep 17 00:00:00 2001 From: Gabriel Adrian Samfira Date: Thu, 11 May 2023 22:00:10 +0300 Subject: [PATCH 1/2] Write short form hostname While setting the hostname as a FQDN is perfectly valid, in most cases the expectation is that /etc/hostname holds the short form hostname and the FQDN is added as a canonical hostname, i.e. as the first column in /etc/hosts after the local IP address. This will allow clients to use: hostname -f to get the fqdn and still be able to get the host form hostname by calling: hostname Signed-off-by: Gabriel Adrian Samfira --- src/providers/mod.rs | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/providers/mod.rs b/src/providers/mod.rs index b2b30c9e..2ca9b933 100644 --- a/src/providers/mod.rs +++ b/src/providers/mod.rs @@ -241,6 +241,16 @@ pub trait MetadataProvider { fn write_hostname(&self, hostname_file_path: String) -> Result<()> { if let Some(mut hostname) = self.hostname()? { if let Some(maxlen) = max_hostname_len()? { + // Get the short form hostname (i.e. without the domain name). + // The domain name is usually set as a search domain via DHCP, and + // it can optionally be added as a canonical hostname to /etc/hosts + // as well, as the first value after the local IP address. + // + // Example: + // 127.0.0.1 example.local example + if let Some(idx) = hostname.find('.') { + hostname.truncate(idx); + } if hostname.len() > maxlen { // Value exceeds the system's maximum hostname length. // Truncate hostname to the first dot, or to the maximum @@ -252,9 +262,6 @@ pub trait MetadataProvider { maxlen ); hostname.truncate(maxlen); - if let Some(idx) = hostname.find('.') { - hostname.truncate(idx); - } } } @@ -334,7 +341,7 @@ mod tests { // simple FQDN assert_eq!( try_write_hostname("hostname7.example.com"), - "hostname7.example.com" + "hostname7" ); // truncated simple hostname assert_eq!( From 84f851d38f54e95eb4b22c88bbcdf3ef8db9cdbd Mon Sep 17 00:00:00 2001 From: Gabriel Adrian Samfira Date: Fri, 12 May 2023 10:51:03 +0300 Subject: [PATCH 2/2] Add --short command line option The --short command line option is a bool which requires the --hostname option and which will toggles writing the short form hostname to /etc/hostname. Signed-off-by: Gabriel Adrian Samfira --- src/cli/multi.rs | 7 +++++-- src/providers/mod.rs | 46 +++++++++++++++++++++++++++----------------- 2 files changed, 33 insertions(+), 20 deletions(-) diff --git a/src/cli/multi.rs b/src/cli/multi.rs index 9e32ef03..2684edbb 100644 --- a/src/cli/multi.rs +++ b/src/cli/multi.rs @@ -21,8 +21,11 @@ pub struct CliMulti { #[arg(long)] check_in: bool, /// The file into which the hostname should be written - #[arg(long = "hostname", value_name = "path")] + #[arg(group = "hostname", long = "hostname", value_name = "path")] hostname_file: Option, + /// Parse the hostname retrieved from metadata as a short hostname + #[arg(long = "short", requires = "hostname")] + short_hostname: bool, /// The directory into which network units are written #[arg(long = "network-units", value_name = "path")] network_units_dir: Option, @@ -64,7 +67,7 @@ impl CliMulti { // write hostname if configured to do so self.hostname_file - .map_or(Ok(()), |x| metadata.write_hostname(x)) + .map_or(Ok(()), |x| metadata.write_hostname(x, self.short_hostname)) .context("writing hostname")?; // write network units if configured to do so diff --git a/src/providers/mod.rs b/src/providers/mod.rs index 2ca9b933..104eda86 100644 --- a/src/providers/mod.rs +++ b/src/providers/mod.rs @@ -238,18 +238,20 @@ pub trait MetadataProvider { Ok(()) } - fn write_hostname(&self, hostname_file_path: String) -> Result<()> { + fn write_hostname(&self, hostname_file_path: String, short: bool) -> Result<()> { if let Some(mut hostname) = self.hostname()? { if let Some(maxlen) = max_hostname_len()? { - // Get the short form hostname (i.e. without the domain name). - // The domain name is usually set as a search domain via DHCP, and - // it can optionally be added as a canonical hostname to /etc/hosts - // as well, as the first value after the local IP address. - // - // Example: - // 127.0.0.1 example.local example - if let Some(idx) = hostname.find('.') { - hostname.truncate(idx); + if short { + // Get the short form hostname (i.e. without the domain name). + // The domain name is usually set as a search domain via DHCP, and + // it can optionally be added as a canonical hostname to /etc/hosts + // as well, as the first value after the local IP address. + // + // Example: + // 127.0.0.1 example.local example + if let Some(idx) = hostname.find('.') { + hostname.truncate(idx); + } } if hostname.len() > maxlen { // Value exceeds the system's maximum hostname length. @@ -262,6 +264,9 @@ pub trait MetadataProvider { maxlen ); hostname.truncate(maxlen); + if let Some(idx) = hostname.find('.') { + hostname.truncate(idx); + } } } @@ -316,11 +321,11 @@ mod tests { } // write specified hostname to a file, then read it back - fn try_write_hostname(hostname: &str) -> String { + fn try_write_hostname(hostname: &str, short: bool) -> String { let mut temp = NamedTempFile::new().unwrap(); let provider = HostnameMock(hostname.into()); provider - .write_hostname(temp.path().to_str().unwrap().into()) + .write_hostname(temp.path().to_str().unwrap().into(), short) .unwrap(); let mut ret = String::new(); temp.read_to_string(&mut ret).unwrap(); @@ -337,30 +342,35 @@ mod tests { .take(maxlen * 2) .collect::(); // simple hostname - assert_eq!(try_write_hostname("hostname7"), "hostname7"); + assert_eq!(try_write_hostname("hostname7", false), "hostname7"); // simple FQDN assert_eq!( - try_write_hostname("hostname7.example.com"), + try_write_hostname("hostname7.example.com", false), + "hostname7.example.com" + ); + // short form hostname + assert_eq!( + try_write_hostname("hostname7.example.com", true), "hostname7" ); // truncated simple hostname assert_eq!( - try_write_hostname(&long_string[0..maxlen + 10]), + try_write_hostname(&long_string[0..maxlen + 10], false), long_string[0..maxlen] ); // truncated FQDN assert_eq!( - try_write_hostname(&format!("{}.example.com", &long_string[0..maxlen + 5])), + try_write_hostname(&format!("{}.example.com", &long_string[0..maxlen + 5]), false), long_string[0..maxlen] ); // truncate to first dot assert_eq!( - try_write_hostname(&format!("{}.example.com", &long_string[0..maxlen - 5])), + try_write_hostname(&format!("{}.example.com", &long_string[0..maxlen - 5]), false), long_string[0..maxlen - 5] ); // truncate to first dot even if we could truncate to second dot assert_eq!( - try_write_hostname(&format!("{}.example.com", &long_string[0..maxlen - 10])), + try_write_hostname(&format!("{}.example.com", &long_string[0..maxlen - 10]), false), long_string[0..maxlen - 10] ); }