switch ports to port pairs
This commit is contained in:
parent
3109edc085
commit
b0cf13ddfb
64
src/state.rs
64
src/state.rs
@ -4,7 +4,6 @@ use crate::constants::*;
|
|||||||
use anyhow::anyhow;
|
use anyhow::anyhow;
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use sha2::{Digest, Sha256};
|
use sha2::{Digest, Sha256};
|
||||||
use std::collections::HashMap;
|
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::fs::remove_file;
|
use std::fs::remove_file;
|
||||||
@ -23,20 +22,21 @@ pub struct Resources {
|
|||||||
reserved_ips: HashSet<String>,
|
reserved_ips: HashSet<String>,
|
||||||
reserved_if_names: HashSet<String>,
|
reserved_if_names: HashSet<String>,
|
||||||
// sha256sum -> absolute path
|
// sha256sum -> absolute path
|
||||||
boot_files: HashMap<String, String>,
|
boot_files: HashSet<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Resources {
|
impl Resources {
|
||||||
fn reserve_ports(&mut self, nr: u16, config: &Config) -> Vec<u16> {
|
fn reserve_ports(&mut self, extra_ports: usize, config: &Config) -> Vec<u16> {
|
||||||
use rand::Rng;
|
use rand::Rng;
|
||||||
if config.public_port_range.len() < self.reserved_ports.len() + nr as usize {
|
let total_ports = extra_ports + 1;
|
||||||
|
if config.public_port_range.len() < self.reserved_ports.len() + total_ports as usize {
|
||||||
return Vec::new();
|
return Vec::new();
|
||||||
}
|
}
|
||||||
if nr > config.max_ports_per_vm {
|
if total_ports > config.max_ports_per_vm as usize {
|
||||||
return Vec::new();
|
return Vec::new();
|
||||||
}
|
}
|
||||||
let mut published_ports = Vec::new();
|
let mut published_ports = Vec::new();
|
||||||
for _ in 0..nr {
|
for _ in 0..total_ports {
|
||||||
for _ in 0..5 {
|
for _ in 0..5 {
|
||||||
let port = rand::thread_rng().gen_range(config.public_port_range.clone());
|
let port = rand::thread_rng().gen_range(config.public_port_range.clone());
|
||||||
if self.reserved_ports.insert(port) {
|
if self.reserved_ports.insert(port) {
|
||||||
@ -45,6 +45,7 @@ impl Resources {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
published_ports.sort();
|
||||||
published_ports
|
published_ports
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -153,8 +154,11 @@ impl Resources {
|
|||||||
if path.is_file() {
|
if path.is_file() {
|
||||||
match compute_sha256(&path) {
|
match compute_sha256(&path) {
|
||||||
Ok(hash) => {
|
Ok(hash) => {
|
||||||
self.boot_files
|
if *hash == *entry.file_name() {
|
||||||
.insert(hash, path.to_string_lossy().to_string());
|
self.boot_files.insert(hash);
|
||||||
|
} else {
|
||||||
|
// TODO: rename file and insert
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Err(e) => return Err(anyhow!("Error computing hash for {:?}: {}", path, e)),
|
Err(e) => return Err(anyhow!("Error computing hash for {:?}: {}", path, e)),
|
||||||
}
|
}
|
||||||
@ -164,10 +168,10 @@ impl Resources {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn download_boot_file(&mut self, url: String, sha: String) -> Result<()> {
|
fn download_boot_file(&mut self, url: String, sha: String) -> Result<()> {
|
||||||
if !self.boot_files.contains_key(&sha) {
|
if !self.boot_files.contains(&sha) {
|
||||||
download_and_check_sha(&url, &sha)?;
|
download_and_check_sha(&url, &sha)?;
|
||||||
}
|
}
|
||||||
self.boot_files.insert(sha, url);
|
self.boot_files.insert(sha);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -246,7 +250,7 @@ pub struct VM {
|
|||||||
uuid: String,
|
uuid: String,
|
||||||
hostname: String,
|
hostname: String,
|
||||||
admin_key: String,
|
admin_key: String,
|
||||||
fw_ports: Vec<u16>,
|
fw_ports: Vec<(u16, u16)>,
|
||||||
nics: Vec<VMNIC>,
|
nics: Vec<VMNIC>,
|
||||||
// currently hardcoded to EPYC-v4
|
// currently hardcoded to EPYC-v4
|
||||||
// cpu_type: String,
|
// cpu_type: String,
|
||||||
@ -263,7 +267,7 @@ pub struct NewVMRequest {
|
|||||||
uuid: String,
|
uuid: String,
|
||||||
hostname: String,
|
hostname: String,
|
||||||
admin_key: String,
|
admin_key: String,
|
||||||
nr_of_fw_ports: u16,
|
extra_ports: Vec<u16>,
|
||||||
public_ipv4: bool,
|
public_ipv4: bool,
|
||||||
public_ipv6: bool,
|
public_ipv6: bool,
|
||||||
disk_size: usize,
|
disk_size: usize,
|
||||||
@ -293,7 +297,7 @@ impl VM {
|
|||||||
config: &Config,
|
config: &Config,
|
||||||
res: &mut Resources,
|
res: &mut Resources,
|
||||||
) -> Result<Self, VMCreationErrors> {
|
) -> Result<Self, VMCreationErrors> {
|
||||||
if req.nr_of_fw_ports > 0 && req.public_ipv4 {
|
if req.extra_ports.len() > 0 && req.public_ipv4 {
|
||||||
return Err(VMCreationErrors::NATandIPv4Conflict);
|
return Err(VMCreationErrors::NATandIPv4Conflict);
|
||||||
}
|
}
|
||||||
if config.max_cores_per_vm < req.vcpus {
|
if config.max_cores_per_vm < req.vcpus {
|
||||||
@ -316,7 +320,7 @@ impl VM {
|
|||||||
if let Err(dtrfs_file_error) = res.download_boot_file(req.dtrfs_url, req.dtrfs_sha.clone())
|
if let Err(dtrfs_file_error) = res.download_boot_file(req.dtrfs_url, req.dtrfs_sha.clone())
|
||||||
{
|
{
|
||||||
return Err(VMCreationErrors::BootFileError(format!(
|
return Err(VMCreationErrors::BootFileError(format!(
|
||||||
"Could not get kernel: {dtrfs_file_error:?}"
|
"Could not get dtrfs: {dtrfs_file_error:?}"
|
||||||
)));
|
)));
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -353,8 +357,11 @@ impl VM {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let fw_ports = res.reserve_ports(req.nr_of_fw_ports, &config);
|
let mut host_ports: Vec<u16> = Vec::new();
|
||||||
if fw_ports.len() == 0 {
|
let mut port_pairs: Vec<(u16, u16)> = Vec::new();
|
||||||
|
if !req.public_ipv4 {
|
||||||
|
host_ports.append(res.reserve_ports(req.extra_ports.len(), &config).as_mut());
|
||||||
|
if host_ports.len() == 0 {
|
||||||
for nic in vm_nics {
|
for nic in vm_nics {
|
||||||
for ip in nic.ips {
|
for ip in nic.ips {
|
||||||
res.reserved_ips.remove(&ip.address);
|
res.reserved_ips.remove(&ip.address);
|
||||||
@ -362,6 +369,11 @@ impl VM {
|
|||||||
}
|
}
|
||||||
return Err(VMCreationErrors::NotEnoughPorts);
|
return Err(VMCreationErrors::NotEnoughPorts);
|
||||||
}
|
}
|
||||||
|
port_pairs.push((host_ports[0], 22));
|
||||||
|
for i in 0..req.extra_ports.len() {
|
||||||
|
port_pairs.push((host_ports[i+1], req.extra_ports[i]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Ok(VM {
|
Ok(VM {
|
||||||
uuid: req.uuid,
|
uuid: req.uuid,
|
||||||
@ -373,7 +385,7 @@ impl VM {
|
|||||||
disk_size: req.disk_size,
|
disk_size: req.disk_size,
|
||||||
kernel_sha: req.kernel_sha,
|
kernel_sha: req.kernel_sha,
|
||||||
dtrfs_sha: req.dtrfs_sha,
|
dtrfs_sha: req.dtrfs_sha,
|
||||||
fw_ports,
|
fw_ports: port_pairs,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -433,8 +445,22 @@ impl VM {
|
|||||||
i += 1;
|
i += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
vars += &format!("KERNEL={}\n", VM_BOOT_DIR.to_string() + "/" + &self.kernel_sha);
|
let mut ports = String::new();
|
||||||
vars += &format!("INITRD={}\n", VM_BOOT_DIR.to_string() + "/" + &self.dtrfs_sha);
|
for port in self.fw_ports.iter() {
|
||||||
|
ports += &format!("{}:{} ", port.0, port.1);
|
||||||
|
}
|
||||||
|
if ports != "" {
|
||||||
|
vars += &format!("NAT_PORT_FW={}", ports.trim_end());
|
||||||
|
}
|
||||||
|
|
||||||
|
vars += &format!(
|
||||||
|
"KERNEL={}\n",
|
||||||
|
VM_BOOT_DIR.to_string() + "/" + &self.kernel_sha
|
||||||
|
);
|
||||||
|
vars += &format!(
|
||||||
|
"INITRD={}\n",
|
||||||
|
VM_BOOT_DIR.to_string() + "/" + &self.dtrfs_sha
|
||||||
|
);
|
||||||
vars += &format!("PARAMS={}\n", self.kernel_params());
|
vars += &format!("PARAMS={}\n", self.kernel_params());
|
||||||
vars += &format!("CPU_TYPE={}\n", QEMU_VM_CPU_TYPE);
|
vars += &format!("CPU_TYPE={}\n", QEMU_VM_CPU_TYPE);
|
||||||
vars += &format!("VCPUS={}\n", self.vcpus);
|
vars += &format!("VCPUS={}\n", self.vcpus);
|
||||||
|
@ -16,7 +16,7 @@ pub struct ResourceAllocation {
|
|||||||
pub vcpus: usize,
|
pub vcpus: usize,
|
||||||
pub memory: usize,
|
pub memory: usize,
|
||||||
pub storage: usize,
|
pub storage: usize,
|
||||||
pub published_ports: Vec<u16>,
|
pub extra_ports: Vec<u16>,
|
||||||
// storage tier: not part of MVP
|
// storage tier: not part of MVP
|
||||||
// pub storage_tier: usize,
|
// pub storage_tier: usize,
|
||||||
pub public_ipv4: Option<String>,
|
pub public_ipv4: Option<String>,
|
||||||
|
Loading…
Reference in New Issue
Block a user