src/config/network.rs: impleement load/save
This commit is contained in:
		@ -3,6 +3,8 @@ use std::collections::{HashSet, HashMap};
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
use anyhow::{Error, bail};
 | 
					use anyhow::{Error, bail};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use proxmox::tools::{fs::replace_file, fs::CreateOptions};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
mod helper;
 | 
					mod helper;
 | 
				
			||||||
pub use helper::*;
 | 
					pub use helper::*;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -284,3 +286,44 @@ impl NetworkConfig {
 | 
				
			|||||||
        Ok(())
 | 
					        Ok(())
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub const NETWORK_INTERFACES_FILENAME: &str = "/etc/network/interfaces";
 | 
				
			||||||
 | 
					pub const NETWORK_LOCKFILE: &str = "/var/lock/pve-network.lck";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub fn config() -> Result<(NetworkConfig, [u8;32]), Error> {
 | 
				
			||||||
 | 
					    let content = match std::fs::read(NETWORK_INTERFACES_FILENAME) {
 | 
				
			||||||
 | 
					        Ok(c) => c,
 | 
				
			||||||
 | 
					        Err(err) => {
 | 
				
			||||||
 | 
					            if err.kind() == std::io::ErrorKind::NotFound {
 | 
				
			||||||
 | 
					                Vec::new()
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                bail!("unable to read '{}' - {}", NETWORK_INTERFACES_FILENAME, err);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let digest = openssl::sha::sha256(&content);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let mut parser = NetworkParser::new(&content[..]);
 | 
				
			||||||
 | 
					    let data = parser.parse_interfaces()?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Ok((data, digest))
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub fn save_config(config: &NetworkConfig) -> Result<(), Error> {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let mut raw = Vec::new();
 | 
				
			||||||
 | 
					    config.write_config(&mut raw)?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let mode = nix::sys::stat::Mode::from_bits_truncate(0o0644);
 | 
				
			||||||
 | 
					    // set the correct owner/group/permissions while saving file
 | 
				
			||||||
 | 
					    // owner(rw) = root, group(r)=root, others(r)
 | 
				
			||||||
 | 
					    let options = CreateOptions::new()
 | 
				
			||||||
 | 
					        .perm(mode)
 | 
				
			||||||
 | 
					        .owner(nix::unistd::ROOT)
 | 
				
			||||||
 | 
					        .group(nix::unistd::Gid::from_raw(0));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    replace_file(NETWORK_INTERFACES_FILENAME, &raw, options)?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Ok(())
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -1,5 +1,4 @@
 | 
				
			|||||||
use std::io::{BufReader};
 | 
					use std::io::{BufRead};
 | 
				
			||||||
use std::fs::File;
 | 
					 | 
				
			||||||
use std::iter::{Peekable, Iterator};
 | 
					use std::iter::{Peekable, Iterator};
 | 
				
			||||||
use std::collections::HashSet;
 | 
					use std::collections::HashSet;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -14,15 +13,14 @@ use super::lexer::*;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
use super::{NetworkConfig, NetworkOrderEntry, Interface, ConfigMethod};
 | 
					use super::{NetworkConfig, NetworkOrderEntry, Interface, ConfigMethod};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub struct NetworkParser {
 | 
					pub struct NetworkParser<R: BufRead> {
 | 
				
			||||||
    input: Peekable<Lexer<BufReader<File>>>,
 | 
					    input: Peekable<Lexer<R>>,
 | 
				
			||||||
    line_nr: usize,
 | 
					    line_nr: usize,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl NetworkParser {
 | 
					impl <R: BufRead> NetworkParser<R> {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pub fn new(file: File) -> Self {
 | 
					    pub fn new(reader: R) -> Self {
 | 
				
			||||||
        let reader = BufReader::new(file);
 | 
					 | 
				
			||||||
        let input = Lexer::new(reader).peekable();
 | 
					        let input = Lexer::new(reader).peekable();
 | 
				
			||||||
        Self { input, line_nr: 1 }
 | 
					        Self { input, line_nr: 1 }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -328,7 +326,7 @@ impl NetworkParser {
 | 
				
			|||||||
            if let Some(interface) = config.interfaces.get_mut(iface) {
 | 
					            if let Some(interface) = config.interfaces.get_mut(iface) {
 | 
				
			||||||
                interface.exists = exists;
 | 
					                interface.exists = exists;
 | 
				
			||||||
                interface.active = *active;
 | 
					                interface.active = *active;
 | 
				
			||||||
            } else if exists { // also add physical NICs
 | 
					            } else if exists { // also add all physical NICs
 | 
				
			||||||
                let mut interface = Interface::new(iface.clone());
 | 
					                let mut interface = Interface::new(iface.clone());
 | 
				
			||||||
                interface.set_method_v4(ConfigMethod::Manual)?;
 | 
					                interface.set_method_v4(ConfigMethod::Manual)?;
 | 
				
			||||||
                interface.exists = true;
 | 
					                interface.exists = true;
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user