From a9bb491e3527513ec9b28cc5d580e4f080784427 Mon Sep 17 00:00:00 2001 From: Dietmar Maurer Date: Tue, 21 Apr 2020 11:06:22 +0200 Subject: [PATCH] src/config/network.rs: cleanup autostart flag handling --- src/config/network.rs | 155 ++++++++++++++++++----------------- src/config/network/parser.rs | 34 ++++++-- 2 files changed, 104 insertions(+), 85 deletions(-) diff --git a/src/config/network.rs b/src/config/network.rs index 9130555d..f64ce1a4 100644 --- a/src/config/network.rs +++ b/src/config/network.rs @@ -22,6 +22,7 @@ pub enum ConfigMethod { #[derive(Debug)] pub struct Interface { + pub autostart: bool, pub name: String, pub method_v4: Option, pub method_v6: Option, @@ -38,8 +39,9 @@ pub struct Interface { impl Interface { pub fn new(name: String) -> Self { - Self { + Self { name, + autostart: false, method_v4: None, method_v6: None, address_v4: None, @@ -140,6 +142,78 @@ impl Interface { self.options_v4.push(text); } } + + fn write_iface_attributes_v4(&self, w: &mut dyn Write) -> Result<(), Error> { + if let Some(address) = &self.address_v4 { + if let Some(netmask) = self.netmask_v4 { + writeln!(w, " address {}/{}", address, netmask)?; + } else { + writeln!(w, " address {}", address)?; + } + } + if let Some(gateway) = &self.gateway_v4 { + writeln!(w, " gateway {}", gateway)?; + } + for option in &self.options_v4 { + writeln!(w, " {}", option)?; + } + + Ok(()) + } + + fn write_iface_attributes_v6(&self, w: &mut dyn Write) -> Result<(), Error> { + if let Some(address) = &self.address_v6 { + if let Some(netmask) = self.netmask_v6 { + writeln!(w, " address {}/{}", address, netmask)?; + } else { + writeln!(w, " address {}", address)?; + } + } + if let Some(gateway) = &self.gateway_v6 { + writeln!(w, " gateway {}", gateway)?; + } + for option in &self.options_v6 { + writeln!(w, " {}", option)?; + } + + Ok(()) + } + + fn write_iface(&self, w: &mut dyn Write) -> Result<(), Error> { + + fn method_to_str(method: ConfigMethod) -> &'static str { + match method { + ConfigMethod::Static => "static", + ConfigMethod::Loopback => "loopback", + ConfigMethod::Manual => "manual", + ConfigMethod::DHCP => "dhcp", + } + } + + if self.autostart { + writeln!(w, "auto {}", self.name)?; + } + + if self.method_v4 == self.method_v6 { + let method = self.method_v4.unwrap_or(ConfigMethod::Static); + writeln!(w, "iface {} {}", self.name, method_to_str(method))?; + self.write_iface_attributes_v4(w)?; + self.write_iface_attributes_v6(w)?; + writeln!(w)?; + } else { + if let Some(method) = self.method_v4 { + writeln!(w, "iface {} inet {}", self.name, method_to_str(method))?; + self.write_iface_attributes_v4(w)?; + writeln!(w)?; + } + if let Some(method) = self.method_v6 { + writeln!(w, "iface {} inet6 {}", self.name, method_to_str(method))?; + self.write_iface_attributes_v6(w)?; + writeln!(w)?; + } + } + Ok(()) + } } #[derive(Debug)] @@ -151,7 +225,6 @@ enum NetworkOrderEntry { #[derive(Debug)] pub struct NetworkConfig { - pub auto_flag: HashSet, interfaces: HashMap, order: Vec, } @@ -160,7 +233,6 @@ impl NetworkConfig { pub fn new() -> Self { Self { - auto_flag: HashSet::new(), interfaces: HashMap::new(), order: Vec::new(), } @@ -168,83 +240,12 @@ impl NetworkConfig { pub fn write_config(&self, w: &mut dyn Write) -> Result<(), Error> { - fn method_to_str(method: ConfigMethod) -> &'static str { - match method { - ConfigMethod::Static => "static", - ConfigMethod::Loopback => "loopback", - ConfigMethod::Manual => "manual", - ConfigMethod::DHCP => "dhcp", - } - } - - fn write_attributes_v4(w: &mut dyn Write, interface: &Interface) -> Result<(), Error> { - if let Some(address) = &interface.address_v4 { - if let Some(netmask) = interface.netmask_v4 { - writeln!(w, " address {}/{}", address, netmask)?; - } else { - writeln!(w, " address {}", address)?; - } - } - if let Some(gateway) = &interface.gateway_v4 { - writeln!(w, " gateway {}", gateway)?; - } - for option in &interface.options_v4 { - writeln!(w, " {}", option)?; - } - - Ok(()) - }; - - fn write_attributes_v6(w: &mut dyn Write, interface: &Interface) -> Result<(), Error> { - if let Some(address) = &interface.address_v6 { - if let Some(netmask) = interface.netmask_v6 { - writeln!(w, " address {}/{}", address, netmask)?; - } else { - writeln!(w, " address {}", address)?; - } - } - if let Some(gateway) = &interface.gateway_v6 { - writeln!(w, " gateway {}", gateway)?; - } - for option in &interface.options_v6 { - writeln!(w, " {}", option)?; - } - - Ok(()) - }; - - fn write_interface(w: &mut dyn Write, config: &NetworkConfig, name: &str, interface: &Interface) -> Result<(), Error> { - if config.auto_flag.contains(name) { - writeln!(w, "auto {}", name)?; - } - - if interface.method_v4 == interface.method_v6 { - let method = interface.method_v4.unwrap_or(ConfigMethod::Static); - writeln!(w, "iface {} {}", name, method_to_str(method))?; - write_attributes_v4(w, &interface)?; - write_attributes_v6(w, &interface)?; - writeln!(w)?; - } else { - if let Some(method) = interface.method_v4 { - writeln!(w, "iface {} inet {}", name, method_to_str(method))?; - write_attributes_v4(w, &interface)?; - writeln!(w)?; - } - if let Some(method) = interface.method_v6 { - writeln!(w, "iface {} inet6 {}", name, method_to_str(method))?; - write_attributes_v6(w, &interface)?; - writeln!(w)?; - } - } - Ok(()) - } - let mut done = HashSet::new(); let mut last_entry_was_comment = false; for entry in self.order.iter() { - match entry { + match entry { NetworkOrderEntry::Comment(comment) => { writeln!(w, "#{}", comment)?; last_entry_was_comment = true; @@ -267,14 +268,14 @@ impl NetworkConfig { if done.contains(name) { continue; } done.insert(name); - write_interface(w, self, name, interface)?; + interface.write_iface(w)?; } } } for (name, interface) in &self.interfaces { if done.contains(name) { continue; } - write_interface(w, self, name, interface)?; + interface.write_iface(w)?; } Ok(()) } diff --git a/src/config/network/parser.rs b/src/config/network/parser.rs index 25c8508a..b1ae9f98 100644 --- a/src/config/network/parser.rs +++ b/src/config/network/parser.rs @@ -1,6 +1,7 @@ use std::io::{BufReader}; use std::fs::File; use std::iter::{Peekable, Iterator}; +use std::collections::HashSet; use anyhow::{Error, bail, format_err}; use lazy_static::lazy_static; @@ -70,15 +71,22 @@ impl NetworkParser { Ok(()) } - fn parse_auto(&mut self, config: &mut NetworkConfig) -> Result<(), Error> { + fn parse_auto(&mut self, auto_flag: &mut HashSet) -> Result<(), Error> { self.eat(Token::Auto)?; - let iface = self.next_text()?; - println!("AUTO {}", iface); + loop { + match self.next()? { + (Token::Text, iface) => { + println!("AUTO {}", iface); + auto_flag.insert(iface.to_string()); + } + (Token::Newline, _) => break, + unexpected => { + bail!("expected {:?}, got {:?}", Token::Text, unexpected); + } + } - self.eat(Token::Newline)?; - - config.auto_flag.insert(iface.to_string()); + } Ok(()) } @@ -268,13 +276,15 @@ impl NetworkParser { pub fn _parse_interfaces(&mut self) -> Result { let mut config = NetworkConfig::new(); + let mut auto_flag: HashSet = HashSet::new(); + loop { let peek = self.peek()?; println!("TOKEN: {:?}", peek); match peek { Token::EOF => { // fixme: trailing comments - return Ok(config); + break; } Token::Newline => { self.eat(Token::Newline)?; @@ -287,7 +297,7 @@ impl NetworkParser { self.eat(Token::Newline)?; } Token::Auto => { - self.parse_auto(&mut config)?; + self.parse_auto(&mut auto_flag)?; } Token::Iface => { self.parse_iface(&mut config)?; @@ -300,5 +310,13 @@ impl NetworkParser { } } } + + for iface in auto_flag.iter() { + if let Some(interface) = config.interfaces.get_mut(iface) { + interface.autostart = true; + } + } + + Ok(config) } }