Skip to content

Commit

Permalink
Merge pull request #1 from Apokleos/fmt-fixing
Browse files Browse the repository at this point in the history
cdi-rs: fixing with cargo fmt
  • Loading branch information
zvonkok authored May 17, 2024
2 parents 382844a + e44a8b4 commit 491fbcb
Show file tree
Hide file tree
Showing 11 changed files with 579 additions and 546 deletions.
140 changes: 80 additions & 60 deletions src/annotations.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use std::vec::Vec;
use anyhow::{anyhow, Result};
use std::collections::HashMap;
use anyhow::{Result, anyhow};
use std::vec::Vec;

use crate::parser as parser;
use crate::parser;

const ANNOTATION_PREFIX: &str = "cdi.k8s.io/";
const MAX_NAME_LEN: usize = 63;
Expand Down Expand Up @@ -31,7 +31,6 @@ pub(crate) fn parse_annotations(
continue;
}


for device in v.split(',') {
match parser::parse_qualified_name(device) {
Err(_) => return Err(anyhow!("invalid CDI device name {}", device)),
Expand Down Expand Up @@ -64,23 +63,37 @@ pub(crate) fn annotation_key(plugin_name: &str, device_id: &str) -> Result<Strin

if let Some(first) = name.chars().next() {
if !first.is_alphanumeric() {
return Err(anyhow!("invalid name {:?}, first '{}' should be alphanumeric", name, first));
return Err(anyhow!(
"invalid name {:?}, first '{}' should be alphanumeric",
name,
first
));
}
}

if name.len() > 2 {
for c in name[1..name.len() - 1].chars() {
match c {
c if c.is_alphanumeric() => {},
'_' | '-' | '.' => {},
_ => return Err(anyhow!("invalid name {:?}, invalid character '{}'", name, c)),
c if c.is_alphanumeric() => {}
'_' | '-' | '.' => {}
_ => {
return Err(anyhow!(
"invalid name {:?}, invalid character '{}'",
name,
c
))
}
}
}
}

if let Some(last) = name.chars().last() {
if !last.is_alphanumeric() {
return Err(anyhow!("invalid name {:?}, last '{}' should be alphanumeric", name, last));
return Err(anyhow!(
"invalid name {:?}, last '{}' should be alphanumeric",
name,
last
));
}
}

Expand All @@ -103,60 +116,67 @@ pub(crate) fn annotation_value(devices: Vec<String>) -> Result<String, anyhow::E
Ok(value)
}


#[cfg(test)]

mod tests {
use std::collections::HashMap;
use crate::annotations;
use std::collections::HashMap;

#[test]
fn parse_annotations() {
let mut cdi_devices = HashMap::new();

cdi_devices.insert(
"cdi.k8s.io/vfio17".to_string(),
"nvidia.com/gpu=0".to_string(),
);
cdi_devices.insert(
"cdi.k8s.io/vfio18".to_string(),
"nvidia.com/gpu=1".to_string(),
);
cdi_devices.insert(
"cdi.k8s.io/vfio19".to_string(),
"nvidia.com/gpu=all".to_string(),
);

match annotations::parse_annotations(cdi_devices) {
Ok((keys, devices)) => {
assert_eq!(keys.len(), 3);
assert_eq!(devices.len(), 3);
}
Err(e) => {
println!("error: {}", e);
}
}
}

#[test]
fn parse_annotations() {


let mut cdi_devices = HashMap::new();

cdi_devices.insert("cdi.k8s.io/vfio17".to_string(), "nvidia.com/gpu=0".to_string());
cdi_devices.insert("cdi.k8s.io/vfio18".to_string(), "nvidia.com/gpu=1".to_string());
cdi_devices.insert("cdi.k8s.io/vfio19".to_string(), "nvidia.com/gpu=all".to_string());

match annotations::parse_annotations(cdi_devices) {
Ok((keys, devices)) => {
assert_eq!(keys.len(), 3);
assert_eq!(devices.len(), 3);
},
Err(e) => {
println!("error: {}", e);
}
}


}

#[test]
fn annotation_value() {
let devices = vec!["nvidia.com/gpu=0".to_string(), "nvidia.com/gpu=1".to_string()];
match annotations::annotation_value(devices) {
Ok(value) => {
assert_eq!(value, "nvidia.com/gpu=0,nvidia.com/gpu=1");
},
Err(e) => {
println!("error: {}", e);
}
}
}

#[test]
fn annotation_key() {
let plugin_name = "nvida-device-plugin";
let device_id = "gpu=0";
match annotations::annotation_key(plugin_name, device_id) {
Ok(key) => {
assert_eq!(key, "nvidia-device-plugin_gpu=0");
},
Err(e) => {
println!("error: {}", e);
}
}
}
}
fn annotation_value() {
let devices = vec![
"nvidia.com/gpu=0".to_string(),
"nvidia.com/gpu=1".to_string(),
];
match annotations::annotation_value(devices) {
Ok(value) => {
assert_eq!(value, "nvidia.com/gpu=0,nvidia.com/gpu=1");
}
Err(e) => {
println!("error: {}", e);
}
}
}

#[test]
fn annotation_key() {
let plugin_name = "nvida-device-plugin";
let device_id = "gpu=0";
match annotations::annotation_key(plugin_name, device_id) {
Ok(key) => {
assert_eq!(key, "nvidia-device-plugin_gpu=0");
}
Err(e) => {
println!("error: {}", e);
}
}
}
}
10 changes: 4 additions & 6 deletions src/bin/cdi.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
extern crate cdi;
//use clap::{Arg, Subcommand};

extern crate cdi;
//use clap::{Arg, Subcommand};

fn main() {


// Here, you can use your library's functions or structs.
}
// Here, you can use your library's functions or structs.
}
5 changes: 1 addition & 4 deletions src/bin/validate.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@

use anyhow::{anyhow, Result};
use clap::{App, Arg};
use std::io::{self, Read};


extern crate cdi;

use cdi::schema as schema;
use cdi::schema;

fn main() -> Result<()> {
let matches = App::new("validate")
Expand Down Expand Up @@ -56,5 +54,4 @@ fn main() -> Result<()> {
};

//schema::validate(schema_file, &doc_data)

}
120 changes: 59 additions & 61 deletions src/cache.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
use anyhow::Result;
use std::collections::HashMap;

use crate::spec::Spec;
use crate::device::Device;
use crate::spec::Spec;
use crate::watch::Watch;
use std::sync::{Arc, Mutex};

// CacheOption is an option to change some aspect of default CDI behavior.
pub trait CacheOption {
fn apply(&self, cache: &mut Cache);
fn apply(&self, cache: &mut Cache);
}

// WithAutoRefresh returns an option to control automatic Cache refresh.
Expand All @@ -19,74 +19,72 @@ pub trait CacheOption {
pub struct WithAutoRefresh(pub bool);

impl CacheOption for WithAutoRefresh {
fn apply(&self, cache: &mut Cache) {
cache.auto_refresh = self.0;
}
fn apply(&self, cache: &mut Cache) {
cache.auto_refresh = self.0;
}
}

pub struct Cache {
spec_dirs:Vec<String>,
specs: HashMap<String, Vec<Spec>>,
devices: HashMap<String, Device>,
errors: HashMap<String, Vec<Box<dyn std::error::Error + Send + Sync + 'static>>>,
dir_errors: HashMap<String, Box<dyn std::error::Error + Send + Sync + 'static>>,

auto_refresh: bool,
watch: Watch,
}
spec_dirs: Vec<String>,
specs: HashMap<String, Vec<Spec>>,
devices: HashMap<String, Device>,
errors: HashMap<String, Vec<Box<dyn std::error::Error + Send + Sync + 'static>>>,
dir_errors: HashMap<String, Box<dyn std::error::Error + Send + Sync + 'static>>,

auto_refresh: bool,
watch: Watch,
}

impl Cache {
pub fn new() -> Arc<Mutex<Cache>> {
Arc::new(Mutex::new(Cache {
spec_dirs: Vec::new(),
specs: HashMap::new(),
devices: HashMap::new(),
errors: HashMap::new(),
dir_errors: HashMap::new(),
auto_refresh: false,
watch: Watch::new(),
}))
}
pub fn configure(&mut self, options: Vec<Box<dyn CacheOption>>) {
for option in options {
option.apply(self);
}
}
pub fn new() -> Arc<Mutex<Cache>> {
Arc::new(Mutex::new(Cache {
spec_dirs: Vec::new(),
specs: HashMap::new(),
devices: HashMap::new(),
errors: HashMap::new(),
dir_errors: HashMap::new(),
auto_refresh: false,
watch: Watch::new(),
}))
}
pub fn configure(&mut self, options: Vec<Box<dyn CacheOption>>) {
for option in options {
option.apply(self);
}
}

pub fn list_vendors(&self) -> Vec<String> {
pub fn list_vendors(&self) -> Vec<String> {
let mut vendors: Vec<String> = Vec::new();

let mut vendors: Vec<String> = Vec::new();
self.refresh_if_required(false);

self.refresh_if_required(false);

for vendor in self.specs.keys() {
vendors.push(*vendor);
}
vendors.sort();
vendors
}
pub fn get_vendor_specs(&self, vendor: &str) -> Vec<Spec> {
self.refresh_if_required(false);
for vendor in self.specs.keys() {
vendors.push(*vendor);
}
vendors.sort();
vendors
}
pub fn get_vendor_specs(&self, vendor: &str) -> Vec<Spec> {
self.refresh_if_required(false);

match self.specs.get(vendor) {
Some(specs) => specs.clone(),
None => Vec::new(),
}
}
match self.specs.get(vendor) {
Some(specs) => specs.clone(),
None => Vec::new(),
}
}

fn refresh(&mut self) -> Result<(), Box<dyn std::error::Error>> {
Ok(())
}
fn refresh(&mut self) -> Result<(), Box<dyn std::error::Error>> {
Ok(())
}

fn refresh_if_required(&mut self, force: bool) -> Result<bool, Box<dyn std::error::Error>> {
// We need to refresh if
// - it's forced by an explicit call to Refresh() in manual mode
// - a missing Spec dir appears (added to watch) in auto-refresh mode
if force || (self.auto_refresh && self.watch.update(&mut self.dir_errors, vec![])){
self.refresh()?;
return Ok(true)
}
Ok(false)
}
}
fn refresh_if_required(&mut self, force: bool) -> Result<bool, Box<dyn std::error::Error>> {
// We need to refresh if
// - it's forced by an explicit call to Refresh() in manual mode
// - a missing Spec dir appears (added to watch) in auto-refresh mode
if force || (self.auto_refresh && self.watch.update(&mut self.dir_errors, vec![])) {
self.refresh()?;
return Ok(true);
}
Ok(false)
}
}
15 changes: 7 additions & 8 deletions src/device.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@

// Device represents a CDI device of a Spec.
pub struct Device {
//*cdi.Device
//spec *Spec
pub struct Device {
//*cdi.Device
//spec *Spec
}

impl Device {
pub fn new() -> Device {
Device{}
}
}
pub fn new() -> Device {
Device {}
}
}
Loading

0 comments on commit 491fbcb

Please sign in to comment.