libvirt 0.1.0

Libvirt bindings for rust
Documentation
extern crate libc;

use std::ffi::*;
use std::{string, ptr, mem, slice};
use virt;
use node::NodeInfo;
use domain::VirDomain;
use error::VirError;
use self::libc::funcs::c95::stdlib;

#[derive(Clone)]
pub struct Connection {
    conn: virt::virConnectPtr
}

pub enum ConnectionType {
    OPEN,
    READONLY
    //TODO: Add Auth Option
}

impl Connection {
    pub fn new(uri: String, conntype: ConnectionType) -> Result<Connection, VirError> {
        unsafe {
            let cUri = CString::new(uri).unwrap();
            let ptr: virt::virConnectPtr = match conntype {
                ConnectionType::OPEN => { virt::virConnectOpen(cUri.as_ptr()) },
                ConnectionType::READONLY => { virt::virConnectOpenReadOnly(cUri.as_ptr()) }
            };

            match ptr.is_null() {
                true => Err(VirError::new()),
                false => Ok(Connection{conn:ptr})
            }
        }
    }

    pub fn capabilities(&self) -> Result<String, VirError> {
        unsafe {
            let cap = virt::virConnectGetCapabilities(self.conn);
            match cap.is_null() {
                false => Ok(String::from_utf8_lossy(CStr::from_ptr(cap).to_bytes()).into_owned()),
                true => Err(VirError::new())
            }
        }
    }

    pub fn connection_type(&self) -> Result<String, VirError> {
        unsafe {
            let results = virt::virConnectGetType(self.conn);
            match results.is_null() {
                true => Err(VirError::new()),
                false => Ok(String::from_utf8_lossy(CStr::from_ptr(results).to_bytes()).into_owned())
            }
        }
    }

    pub fn node_info(&self) -> Result<NodeInfo, VirError> {
        unsafe {
            let nptr: virt::virNodeInfoPtr = ptr::null_mut();
            let results = virt::virNodeGetInfo(self.conn, nptr);
            match results == -1 {
                true => Err(VirError::new()),
                false => Ok(NodeInfo{ptr:nptr})
            }
        }
    }

    pub fn hostname(&self) -> Result<String, VirError> {
        unsafe {
            let name = virt::virConnectGetHostname(self.conn);
            match name.is_null() {
                true => Err(VirError::new()),
                false => Ok(String::from_utf8_lossy(CStr::from_ptr(name).to_bytes()).into_owned())
            }
        }
    }

    pub fn version(&self) -> Result<u64, VirError> {
        unsafe {
            let size = mem::size_of::<*mut u64>() as libc::size_t;
            let v: *mut u64 = stdlib::malloc(size) as *mut u64;
            match virt::virConnectGetVersion(self.conn, v) != -1 {
                true => {
                    let ver = v;
                    stdlib::free(v as *mut libc::types::common::c95::c_void);
                    Ok(ver as u64)
                },
                false => {
                    stdlib::free(v as *mut libc::types::common::c95::c_void);
                    Err(VirError::new())
                }
            }
        }
    }

    pub fn libvirt_version(&self) -> Result<u64, VirError> {
        unsafe {
            let size = mem::size_of::<*mut u64>() as libc::size_t;
            let v: *mut u64 = stdlib::malloc(size) as *mut u64;
            match virt::virConnectGetLibVersion(self.conn, v) != -1 {
                true => {
                    let ver = v;
                    stdlib::free(v as *mut libc::types::common::c95::c_void);
                    Ok(ver as u64)
                },
                false => {
                    stdlib::free(v as *mut libc::types::common::c95::c_void);
                    Err(VirError::new())
                },
            }
        }
    }

    pub fn get_type(&self) -> Result<String, VirError> {
        unsafe {
            let name = virt::virConnectGetType(self.conn);
            match name == ptr::null() {
                true => Err(VirError::new()),
                false => Ok(String::from_utf8_lossy(CStr::from_ptr(name).to_bytes()).into_owned())
            }
        }
    }

    pub fn alive(&self) -> Result<(), VirError> {
        unsafe {
            match virt::virConnectIsAlive(self.conn) != -1 {
                true => Ok(()),
                false => Err(VirError::new())
            }
        }
    }

    pub fn encrypted(&self) -> Result<(), VirError> {
        unsafe {
            match virt::virConnectIsEncrypted(self.conn) != -1 {
                true => Ok(()),
                false => Err(VirError::new())
            }
        }
    }

    pub fn secured(&self) -> Result<(), VirError> {
        unsafe {
            match virt::virConnectIsSecure(self.conn) != -1 {
                true => Ok(()),
                false => Err(VirError::new())
            }
        }
    }

    pub fn count_defined_domain(&self) -> Result<i32, VirError> {
        unsafe {
            let count = virt::virConnectNumOfDefinedDomains(self.conn);
            match count == -1 {
                true => Err(VirError::new()),
                false => Ok(count as i32)
            }
        }
    }


    pub fn count_domain(&self) -> Result<i32, VirError> {
        unsafe {
            let count = virt::virConnectNumOfDomains(self.conn);
            match count == -1 {
                true => Err(VirError::new()),
                false => Ok(count as i32)
            }
        }
    }

    pub fn domains(&self) -> Result<Vec<i32>, VirError> {
        unsafe {
            let mut ids = ptr::null_mut();

            let num = virt::virConnectListDomains(self.conn, ids, 1024);

            match num != -1 {
                true => {
                    let mut list: Vec<i32> = Vec::new();
                    let n = slice::from_raw_parts(ids, num as usize);
                    for id in n.to_vec() {
                        list.push(id as i32);
                    }
                    stdlib::free(ids as *mut libc::types::common::c95::c_void);
                    Ok(list)
                },
                false => Err(VirError::new())
            }
        }
    }

    pub fn list_interfaces(&self) -> Result<Vec<String>, VirError> {
        unsafe {
            let count = virt::virConnectNumOfInterfaces(self.conn);
            let mut names = vec![ptr::null_mut(); count as usize];

            match virt::virConnectListInterfaces(self.conn, names.as_mut_ptr(), count) != -1 {
                true => {
                    let mut list: Vec<String> = Vec::new();
                    for name in names {
                        list.push(String::from_utf8_lossy(CStr::from_ptr(name).to_bytes()).into_owned());
                    }
                    Ok(list)
                },
                false => Err(VirError::new())
            }
        }
    }

    pub fn list_all_domains(&self, flags: u32) -> Result<Vec<VirDomain>, VirError> {
        unsafe {
            let mut doms: *mut virt::virDomainPtr = ptr::null_mut();
            let num = virt::virConnectListAllDomains(self.conn, &mut doms, flags);
            match num != -1 {
                true => {
                    let mut list: Vec<VirDomain> = Vec::new();
                    let d = slice::from_raw_parts::<virt::virDomainPtr>(&*doms, num as usize);
                    for dom in d.to_vec() {
                        list.push(VirDomain{ptr: dom});
                    }
                    stdlib::free(doms as *mut libc::types::common::c95::c_void);
                    Ok(list)
                },
                false => {
                    stdlib::free(doms as *mut libc::types::common::c95::c_void);
                    Err(VirError::new())
                }
            }
        }
    }

    pub fn defined_domains(&self) -> Result<Vec<String>, VirError> {
        unsafe {
            let mut names = ptr::null_mut();
            let num = virt::virConnectListDefinedDomains(self.conn, &mut names, 1024);
            match num != -1 {
                true => {
                    let mut list: Vec<String> = Vec::new();
                    let n = slice::from_raw_parts(names, num as usize);
                    for name in n.to_vec() {
                        list.push(String::from_utf8_lossy(CStr::from_ptr(&name).to_bytes()).into_owned());
                    }
                    Ok(list)
                },
                false => Err(VirError::new())
            }
        }
    }

    pub fn list_network(&self) -> Result<Vec<String>, VirError> {
        unsafe {
            let count = virt::virConnectNumOfNetworks(self.conn);
            let mut names = vec![ptr::null_mut(); count as usize];

            match virt::virConnectListNetworks(self.conn, names.as_mut_ptr(), count) != -1 {
                true => {
                    let mut list: Vec<String> = Vec::new();
                    for name in names {
                        list.push(String::from_utf8_lossy(CStr::from_ptr(name).to_bytes()).into_owned());
                    }
                    Ok(list)
                },
                false => Err(VirError::new())
            }
        }
    }

    pub fn list_storage_pool(&self) -> Result<Vec<String>, VirError> {
        unsafe {
            let count = virt::virConnectNumOfStoragePools(self.conn);
            let mut names = vec![ptr::null_mut(); count as usize];

            match virt::virConnectListStoragePools(self.conn, names.as_mut_ptr(), count) != -1 {
                true => {
                    let mut list: Vec<String> = Vec::new();
                    for name in names {
                        list.push(String::from_utf8_lossy(CStr::from_ptr(name).to_bytes()).into_owned());
                    }
                    Ok(list)
                },
                false => Err(VirError::new())
            }
        }
    }

    pub fn lookup_domain_byid(&self, id: i32) -> Result<VirDomain, VirError>  {
        unsafe {
            let dptr = virt::virDomainLookupByID(self.conn, id);

            match dptr.is_null() {
                false => Ok(VirDomain{ptr: dptr}),
                true => Err(VirError::new())
            }

        }
    }

    pub fn lookup_domain_byname(&self, name: &str) -> Result<VirDomain, VirError> {
        unsafe {
            let dptr = virt::virDomainLookupByName(self.conn, CString::new(name).unwrap().as_ptr());
            match dptr.is_null() {
                false => Ok(VirDomain{ptr: dptr}),
                true => Err(VirError::new())
            }
        }
    }

    pub fn create_domain(&self, xml: &str, flags: u32) -> Result<VirDomain, VirError> {
        unsafe {
            let cxml = CString::new(xml).unwrap();
            let pDomain = virt::virDomainCreateXML(self.conn, cxml.as_ptr(), flags);
            match pDomain.is_null() {
                false => Ok(VirDomain{ptr: pDomain}),
                true => Err(VirError::new())
            }
        }
    }

    pub fn define_domain(&self, xml: &str) -> Result<VirDomain, VirError> {
        unsafe {
            let cxml = CString::new(xml).unwrap();
            let pDomain = virt::virDomainDefineXML(self.conn, cxml.as_ptr());

            match pDomain.is_null() {
                true => Err(VirError::new()),
                false => Ok(VirDomain{ptr: pDomain})
            }
        }
    }

    pub fn close(&self) -> Result<(), VirError> {
        unsafe {
            match virt::virConnectClose(self.conn) != -1 {
                true => Ok(()),
                false => Err(VirError::new())
            }
        }
    }
}