src/config/network.rs; support interface comments, cleanups
This commit is contained in:
parent
659c3be3d5
commit
5f60a58fd5
|
@ -586,6 +586,22 @@ pub const NETWORK_INTERFACE_LIST_SCHEMA: Schema = ArraySchema::new(
|
||||||
type: String,
|
type: String,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
comments_v4: {
|
||||||
|
description: "Comments (inet)",
|
||||||
|
type: Array,
|
||||||
|
items: {
|
||||||
|
description: "Comment line.",
|
||||||
|
type: String,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
comments_v6: {
|
||||||
|
description: "Comments (inet6)",
|
||||||
|
type: Array,
|
||||||
|
items: {
|
||||||
|
description: "Comment line.",
|
||||||
|
type: String,
|
||||||
|
},
|
||||||
|
},
|
||||||
bridge_ports: {
|
bridge_ports: {
|
||||||
schema: NETWORK_INTERFACE_LIST_SCHEMA,
|
schema: NETWORK_INTERFACE_LIST_SCHEMA,
|
||||||
optional: true,
|
optional: true,
|
||||||
|
@ -629,6 +645,11 @@ pub struct Interface {
|
||||||
#[serde(skip_serializing_if="Vec::is_empty")]
|
#[serde(skip_serializing_if="Vec::is_empty")]
|
||||||
pub options_v6: Vec<String>,
|
pub options_v6: Vec<String>,
|
||||||
|
|
||||||
|
#[serde(skip_serializing_if="Vec::is_empty")]
|
||||||
|
pub comments_v4: Vec<String>,
|
||||||
|
#[serde(skip_serializing_if="Vec::is_empty")]
|
||||||
|
pub comments_v6: Vec<String>,
|
||||||
|
|
||||||
#[serde(skip_serializing_if="Option::is_none")]
|
#[serde(skip_serializing_if="Option::is_none")]
|
||||||
/// Maximum Transmission Unit
|
/// Maximum Transmission Unit
|
||||||
pub mtu: Option<u64>,
|
pub mtu: Option<u64>,
|
||||||
|
|
|
@ -32,6 +32,8 @@ impl Interface {
|
||||||
gateway_v6: None,
|
gateway_v6: None,
|
||||||
options_v4: Vec::new(),
|
options_v4: Vec::new(),
|
||||||
options_v6: Vec::new(),
|
options_v6: Vec::new(),
|
||||||
|
comments_v4: Vec::new(),
|
||||||
|
comments_v6: Vec::new(),
|
||||||
mtu: None,
|
mtu: None,
|
||||||
bridge_ports: None,
|
bridge_ports: None,
|
||||||
bond_slaves: None,
|
bond_slaves: None,
|
||||||
|
@ -117,14 +119,6 @@ impl Interface {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn push_addon_option(&mut self, text: String) {
|
|
||||||
if self.method_v4.is_none() && self.method_v6.is_some() {
|
|
||||||
self.options_v6.push(text);
|
|
||||||
} else {
|
|
||||||
self.options_v4.push(text);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Write attributes not dependening on address family
|
/// Write attributes not dependening on address family
|
||||||
fn write_iface_attributes(&self, w: &mut dyn Write) -> Result<(), Error> {
|
fn write_iface_attributes(&self, w: &mut dyn Write) -> Result<(), Error> {
|
||||||
|
|
||||||
|
@ -172,6 +166,10 @@ impl Interface {
|
||||||
writeln!(w, " {}", option)?;
|
writeln!(w, " {}", option)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for comment in &self.comments_v4 {
|
||||||
|
writeln!(w, "#4{}", comment)?;
|
||||||
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -190,6 +188,10 @@ impl Interface {
|
||||||
writeln!(w, " {}", option)?;
|
writeln!(w, " {}", option)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for comment in &self.comments_v6 {
|
||||||
|
writeln!(w, "#6{}", comment)?;
|
||||||
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -202,6 +204,8 @@ impl Interface {
|
||||||
method_v6,
|
method_v6,
|
||||||
options_v4,
|
options_v4,
|
||||||
options_v6,
|
options_v6,
|
||||||
|
comments_v4,
|
||||||
|
comments_v6,
|
||||||
// the rest does not matter
|
// the rest does not matter
|
||||||
name: _name,
|
name: _name,
|
||||||
interface_type: _interface_type,
|
interface_type: _interface_type,
|
||||||
|
@ -216,6 +220,8 @@ impl Interface {
|
||||||
bond_slaves: _bond_slaves,
|
bond_slaves: _bond_slaves,
|
||||||
} => {
|
} => {
|
||||||
method_v4 == method_v6
|
method_v4 == method_v6
|
||||||
|
&& comments_v4.is_empty()
|
||||||
|
&& comments_v6.is_empty()
|
||||||
&& options_v4.is_empty()
|
&& options_v4.is_empty()
|
||||||
&& options_v6.is_empty()
|
&& options_v6.is_empty()
|
||||||
}
|
}
|
||||||
|
@ -257,7 +263,9 @@ impl Interface {
|
||||||
if let Some(method) = self.method_v6 {
|
if let Some(method) = self.method_v6 {
|
||||||
writeln!(w, "iface {} inet6 {}", self.name, method_to_str(method))?;
|
writeln!(w, "iface {} inet6 {}", self.name, method_to_str(method))?;
|
||||||
self.write_iface_attributes_v6(w, method)?;
|
self.write_iface_attributes_v6(w, method)?;
|
||||||
|
if self.method_v4.is_none() { // only write common attributes once
|
||||||
self.write_iface_attributes(w)?;
|
self.write_iface_attributes(w)?;
|
||||||
|
}
|
||||||
writeln!(w)?;
|
writeln!(w)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,12 +59,12 @@ impl <R: BufRead> NetworkParser<R> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn eat(&mut self, expected: Token) -> Result<(), Error> {
|
fn eat(&mut self, expected: Token) -> Result<String, Error> {
|
||||||
let (next, _) = self.next()?;
|
let (next, text) = self.next()?;
|
||||||
if next != expected {
|
if next != expected {
|
||||||
bail!("expected {:?}, got {:?}", expected, next);
|
bail!("expected {:?}, got {:?}", expected, next);
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(text)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_auto(&mut self, auto_flag: &mut HashSet<String>) -> Result<(), Error> {
|
fn parse_auto(&mut self, auto_flag: &mut HashSet<String>) -> Result<(), Error> {
|
||||||
|
@ -150,12 +150,6 @@ impl <R: BufRead> NetworkParser<R> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_iface_addon_attribute(&mut self, interface: &mut Interface) -> Result<(), Error> {
|
|
||||||
let option = self.parse_to_eol()?;
|
|
||||||
if !option.is_empty() { interface.push_addon_option(option) };
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn parse_iface_list(&mut self) -> Result<Vec<String>, Error> {
|
fn parse_iface_list(&mut self) -> Result<Vec<String>, Error> {
|
||||||
let mut list = Vec::new();
|
let mut list = Vec::new();
|
||||||
|
|
||||||
|
@ -175,13 +169,29 @@ impl <R: BufRead> NetworkParser<R> {
|
||||||
Ok(list)
|
Ok(list)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_iface_attributes(&mut self, interface: &mut Interface) -> Result<(), Error> {
|
fn parse_iface_attributes(
|
||||||
|
&mut self,
|
||||||
|
interface: &mut Interface,
|
||||||
|
address_family_v4: bool,
|
||||||
|
address_family_v6: bool,
|
||||||
|
) -> Result<(), Error> {
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
match self.peek()? {
|
match self.peek()? {
|
||||||
Token::Attribute => self.eat(Token::Attribute)?,
|
Token::Attribute => { self.eat(Token::Attribute)?; },
|
||||||
|
Token::Comment => {
|
||||||
|
let comment = self.eat(Token::Comment)?;
|
||||||
|
if !address_family_v4 && address_family_v6 {
|
||||||
|
interface.comments_v6.push(comment);
|
||||||
|
} else {
|
||||||
|
interface.comments_v4.push(comment);
|
||||||
|
}
|
||||||
|
self.eat(Token::Newline)?;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
Token::Newline => break,
|
Token::Newline => break,
|
||||||
unexpected => bail!("unknown token {:?}", unexpected),
|
Token::EOF => break,
|
||||||
|
unexpected => bail!("unexpected token {:?} (expected iface attribute)", unexpected),
|
||||||
}
|
}
|
||||||
|
|
||||||
match self.peek()? {
|
match self.peek()? {
|
||||||
|
@ -204,8 +214,16 @@ impl <R: BufRead> NetworkParser<R> {
|
||||||
interface.set_interface_type(NetworkInterfaceType::Bond)?;
|
interface.set_interface_type(NetworkInterfaceType::Bond)?;
|
||||||
}
|
}
|
||||||
Token::Netmask => bail!("netmask is deprecated and no longer supported"),
|
Token::Netmask => bail!("netmask is deprecated and no longer supported"),
|
||||||
_ => {
|
|
||||||
self.parse_iface_addon_attribute(interface)?;
|
_ => { // parse addon attributes
|
||||||
|
let option = self.parse_to_eol()?;
|
||||||
|
if !option.is_empty() {
|
||||||
|
if !address_family_v4 && address_family_v6 {
|
||||||
|
interface.options_v6.push(option);
|
||||||
|
} else {
|
||||||
|
interface.options_v4.push(option);
|
||||||
|
}
|
||||||
|
};
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -235,7 +253,6 @@ impl <R: BufRead> NetworkParser<R> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let has_attributes = self.peek()? == Token::Attribute;
|
|
||||||
let config_method = config_method.unwrap_or(NetworkConfigMethod::Static);
|
let config_method = config_method.unwrap_or(NetworkConfigMethod::Static);
|
||||||
|
|
||||||
if !(address_family_v4 || address_family_v6) {
|
if !(address_family_v4 || address_family_v6) {
|
||||||
|
@ -251,7 +268,7 @@ impl <R: BufRead> NetworkParser<R> {
|
||||||
interface.set_method_v6(config_method)?;
|
interface.set_method_v6(config_method)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
if has_attributes { self.parse_iface_attributes(&mut interface)?; }
|
self.parse_iface_attributes(&mut interface, address_family_v4, address_family_v6)?;
|
||||||
} else {
|
} else {
|
||||||
let mut interface = Interface::new(iface.clone());
|
let mut interface = Interface::new(iface.clone());
|
||||||
if address_family_v4 {
|
if address_family_v4 {
|
||||||
|
@ -261,7 +278,7 @@ impl <R: BufRead> NetworkParser<R> {
|
||||||
interface.set_method_v6(config_method)?;
|
interface.set_method_v6(config_method)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
if has_attributes { self.parse_iface_attributes(&mut interface)?; }
|
self.parse_iface_attributes(&mut interface, address_family_v4, address_family_v6)?;
|
||||||
|
|
||||||
config.interfaces.insert(interface.name.clone(), interface);
|
config.interfaces.insert(interface.name.clone(), interface);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue