pub fn bind_and_run(
        &mut self,
        path: PathBuf,
        process_time_reporter: ProcessTimeReporter,
        seccomp_filter: BpfProgramRef,
        maybe_request_size: Option<usize>,
    ) -> Result<()> {
        let mut server = HttpServer::new(path).unwrap_or_else(|e| {
            error!("Error creating the HTTP server: {}", e);
            std::process::exit(vmm::FC_EXIT_CODE_GENERIC_ERROR);
        });
        if let Some(request_size) = maybe_request_size {
            server.set_payload_max_size(request_size);
        }

        // Store process start time metric.
        process_time_reporter.report_start_time();
        // Store process CPU start time metric.
        process_time_reporter.report_cpu_start_time();

        // Load seccomp filters on the API thread.
        // Execution panics if filters cannot be loaded, use --no-seccomp if skipping filters
        // altogether is the desired behaviour.
        if let Err(e) = seccompiler::apply_filter(seccomp_filter) {
            panic!(
                "Failed to set the requested seccomp filters on the API thread: Error: {:?}",
                e
            );
        }

        server.start_server().expect("Cannot start HTTP server");

        loop {
            let request_vec = match server.requests() {
                Ok(vec) => vec,
                Err(e) => {
                    // print request error, but keep server running
                    error!(
                        "API Server error on retrieving incoming request. Error: {}",
                        e
                    );
                    continue;
                }
            };
            for server_request in request_vec {
                let request_processing_start_us =
                    utils::time::get_time_us(utils::time::ClockType::Monotonic);
                server
                    .respond(
                        // Use `self.handle_request()` as the processing callback.
                        server_request.process(|request| {
                            self.handle_request(request, request_processing_start_us)
                        }),
                    )
                    .or_else(|e| {
                        error!("API Server encountered an error on response: {}", e);
                        Ok(())
                    })?;

                let delta_us = utils::time::get_time_us(utils::time::ClockType::Monotonic)
                    - request_processing_start_us;
                debug!("Total previous API call duration: {} us.", delta_us);

                if self.shutdown_flag {
                    server.flush_outgoing_writes();
                    debug!(
                        "/shutdown-internal request received, API server thread now ending itself"
                    );
                    return Ok(());
                }
            }
        }
    }
/// Starts the HTTP Server by binding to the socket path provided as
/// an argument.
///
/// # Arguments
///
/// * `path` - the socket path on which the server will wait for requests.
/// * `start_time_us` - the timestamp for when the process was started in us.
/// * `start_time_cpu_us` - the timestamp for when the process was started in CPU us.
/// * `seccomp_filter` - the seccomp filter to apply.
///
/// # Example
///
/// ```
/// use mmds::MAX_DATA_STORE_SIZE;
/// use api_server::ApiServer;
/// use mmds::MMDS;
/// use std::{
///     convert::TryInto, io::Read, io::Write, os::unix::net::UnixStream, path::PathBuf,
///     sync::mpsc::channel, thread, time::Duration,
/// };
/// use std::env::consts::ARCH;
/// use utils::{eventfd::EventFd, tempfile::TempFile};
/// use logger::ProcessTimeReporter;
/// use vmm::rpc_interface::VmmData;
/// use vmm::seccomp_filters::{get_filters, SeccompConfig};
/// use vmm::vmm_config::instance_info::InstanceInfo;
///
/// let mut tmp_socket = TempFile::new().unwrap();
/// tmp_socket.remove().unwrap();
/// let path_to_socket = tmp_socket.as_path().to_str().unwrap().to_owned();
/// let api_thread_path_to_socket = path_to_socket.clone();
/// let to_vmm_fd = EventFd::new(libc::EFD_NONBLOCK).unwrap();
/// let (api_request_sender, _from_api) = channel();
/// let (to_api, vmm_response_receiver) = channel();
/// let mmds_info = MMDS.clone();
/// let time_reporter = ProcessTimeReporter::new(Some(1), Some(1), Some(1));
/// let seccomp_filters = get_filters(SeccompConfig::None).unwrap();
/// let payload_limit = Some(MAX_DATA_STORE_SIZE);
///
/// thread::Builder::new()
///     .name("fc_api_test".to_owned())
///     .spawn(move || {
///         ApiServer::new(
///             mmds_info,
///             api_request_sender,
///             vmm_response_receiver,
///             to_vmm_fd,
///         )
///         .bind_and_run(
///             PathBuf::from(api_thread_path_to_socket),
///             time_reporter,
///             seccomp_filters.get("api").unwrap(),
///             payload_limit,
///         )
///         .unwrap();
///     })
///     .unwrap();
///
/// thread::sleep(Duration::from_millis(10));
/// to_api
///     .send(Box::new(Ok(VmmData::InstanceInformation(
///         InstanceInfo::default(),
///     ))))
///     .unwrap();
/// let mut sock = UnixStream::connect(PathBuf::from(path_to_socket)).unwrap();
/// // Send a GET instance-info request.
/// assert!(sock.write_all(b"GET / HTTP/1.1\r\n\r\n").is_ok());
/// let mut buf: [u8; 100] = [0; 100];
/// assert!(sock.read(&mut buf[..]).unwrap() > 0);
/// ```
Starts the HTTP Server by binding to the socket path provided as
an argument.
Starts the HTTP Server by binding to the socket path provided as an argument .
pub fn bind_and_run(
        &mut self,
        path: PathBuf,
        process_time_reporter: ProcessTimeReporter,
        seccomp_filter: BpfProgramRef,
        maybe_request_size: Option<usize>,
    ) -> Result<()> {
        let mut server = HttpServer::new(path).unwrap_or_else(|e| {
            error!("Error creating the HTTP server: {}", e);
            std::process::exit(vmm::FC_EXIT_CODE_GENERIC_ERROR);
        });
        if let Some(request_size) = maybe_request_size {
            server.set_payload_max_size(request_size);
        }
        // Store process start time metric.
        process_time_reporter.report_start_time();
        // Store process CPU start time metric.
        process_time_reporter.report_cpu_start_time();
        // Load seccomp filters on the API thread.
        // Execution panics if filters cannot be loaded, use --no-seccomp if skipping filters
        // altogether is the desired behaviour.
        if let Err(e) = seccompiler::apply_filter(seccomp_filter) {
            panic!(
                "Failed to set the requested seccomp filters on the API thread: Error: {:?}",
                e
            );
        }
        server.start_server().expect("Cannot start HTTP server");
        loop {
            let request_vec = match server.requests() {
                Ok(vec) => vec,
                Err(e) => {
                    // print request error, but keep server running
                    error!(
                        "API Server error on retrieving incoming request. Error: {}",
                        e
                    );
                    continue;
                }
            };
            for server_request in request_vec {
                let request_processing_start_us =
                    utils::time::get_time_us(utils::time::ClockType::Monotonic);
                server
                    .respond(
                        // Use `self.handle_request()` as the processing callback.
                        server_request.process(|request| {
                            self.handle_request(request, request_processing_start_us)
                        }),
                    )
                    .or_else(|e| {
                        error!("API Server encountered an error on response: {}", e);
                        Ok(())
                    })?;
                let delta_us = utils::time::get_time_us(utils::time::ClockType::Monotonic)
                    - request_processing_start_us;
                debug!("Total previous API call duration: {} us.", delta_us);
                if self.shutdown_flag {
                    server.flush_outgoing_writes();
                    debug!(
                        "/shutdown-internal request received, API server thread now ending itself"
                    );
                    return Ok(());
                }
            }
        }
    }
pub fn bind_and_run ( & mut self , path : PathBuf , process_time_reporter : ProcessTimeReporter , seccomp_filter : BpfProgramRef , maybe_request_size : Option < usize > , ) -> Result < ( ) > { let mut server = HttpServer :: new ( path ) . unwrap_or_else ( | e | { error ! ( " " e ) ; std :: process :: exit ( vmm :: FC_EXIT_CODE_GENERIC_ERROR ) ; } ) ; if let Some ( request_size ) = maybe_request_size { server . set_payload_max_size ( request_size ) ; } // Store process start time metric. process_time_reporter . report_start_time ( ) ; // Store process CPU start time metric. process_time_reporter . report_cpu_start_time ( ) ; // Load seccomp filters on the API thread. // Execution panics if filters cannot be loaded, use --no-seccomp if skipping filters // altogether is the desired behaviour. if let Err ( e ) = seccompiler :: apply_filter ( seccomp_filter ) { panic ! ( " " e ) ; } server . start_server ( ) . expect ( " " ) ; loop { let request_vec = match server . requests ( ) { Ok ( vec ) => vec , Err ( e ) => { // print request error, but keep server running error ! ( " " e ) ; continue ; } } ; for server_request in request_vec { let request_processing_start_us = utils :: time :: get_time_us ( utils :: time :: ClockType :: Monotonic ) ; server . respond ( // Use `self.handle_request()` as the processing callback. server_request . process ( | request | { self . handle_request ( request , request_processing_start_us ) } ) , ) . or_else ( | e | { error ! ( " " e ) ; Ok ( ( ) ) } ) ? ; let delta_us = utils :: time :: get_time_us ( utils :: time :: ClockType :: Monotonic ) - request_processing_start_us ; debug ! ( " " delta_us ) ; if self . shutdown_flag { server . flush_outgoing_writes ( ) ; debug ! ( " " ) ; return Ok ( ( ) ) ; } } } }
Starts the HTTP Server by binding to the socket path provided as
an argument.
Starts the HTTP Server by binding to the socket path provided as an argument .
&mut self
path
PathBuf
process_time_reporter
ProcessTimeReporter
seccomp_filter
BpfProgramRef
maybe_request_size
Option<usize>
&mut self
path
PathBuf
process_time_reporter
ProcessTimeReporter
seccomp_filter
BpfProgramRef
maybe_request_size
Option<usize>
example
```
use mmds::MAX_DATA_STORE_SIZE;
use api_server::ApiServer;
use mmds::MMDS;
use std::{
convert::TryInto, io::Read, io::Write, os::unix::net::UnixStream, path::PathBuf,
sync::mpsc::channel, thread, time::Duration,
};
use std::env::consts::ARCH;
use utils::{eventfd::EventFd, tempfile::TempFile};
use logger::ProcessTimeReporter;
use vmm::rpc_interface::VmmData;
use vmm::seccomp_filters::{get_filters, SeccompConfig};
use vmm::vmm_config::instance_info::InstanceInfo.

let mut tmp_socket = TempFile::new().unwrap();
tmp_socket.remove().unwrap();
let path_to_socket = tmp_socket.as_path().to_str().unwrap().to_owned();
let api_thread_path_to_socket = path_to_socket.clone();
let to_vmm_fd = EventFd::new(libc::EFD_NONBLOCK).unwrap();
let (api_request_sender, _from_api) = channel();
let (to_api, vmm_response_receiver) = channel();
let mmds_info = MMDS.clone();
let time_reporter = ProcessTimeReporter::new(Some(1), Some(1), Some(1));
let seccomp_filters = get_filters(SeccompConfig::None).unwrap();
let payload_limit = Some(MAX_DATA_STORE_SIZE).

:Builder::new()
.name("fc_api_test".to_owned())
.spawn(move || {
ApiServer::new(
mmds_info,
api_request_sender,
vmm_response_receiver,
to_vmm_fd,
)
.bind_and_run(
PathBuf::from(api_thread_path_to_socket),
time_reporter,
seccomp_filters.get("api").unwrap(),
payload_limit,
)
.unwrap();
})
.unwrap().

:sleep(Duration::from_millis(10));
to_api
.send(Box::new(Ok(VmmData::InstanceInformation(
InstanceInfo::default(),
))))
.unwrap();
let mut sock = UnixStream::connect(PathBuf::from(path_to_socket)).unwrap();
Send a GET instance-info request.
` ` ` use mmds :: MAX_DATA_STORE_SIZE ; use api_server :: ApiServer ; use mmds :: MMDS ; use std :: { convert :: TryInto io :: Read io :: Write os :: unix :: net :: UnixStream path :: PathBuf sync :: mpsc :: channel thread time :: Duration } ; use std :: env :: consts :: ARCH ; use utils :: { eventfd :: EventFd tempfile :: TempFile } ; use logger :: ProcessTimeReporter ; use vmm :: rpc_interface :: VmmData ; use vmm :: seccomp_filters :: { get_filters SeccompConfig } ; use vmm :: vmm_config :: instance_info :: InstanceInfo . let mut tmp_socket = TempFile :: new () . unwrap () ; tmp_socket . remove () . unwrap () ; let path_to_socket = tmp_socket . as_path () . to_str () . unwrap () . to_owned () ; let api_thread_path_to_socket = path_to_socket . clone () ; let to_vmm_fd = EventFd :: new ( libc :: EFD_NONBLOCK ) . unwrap () ; let ( api_request_sender _from_api ) = channel () ; let ( to_api vmm_response_receiver ) = channel () ; let mmds_info = MMDS . clone () ; let time_reporter = ProcessTimeReporter :: new ( Some ( 1 ) Some ( 1 ) Some ( 1 )) ; let seccomp_filters = get_filters ( SeccompConfig :: None ) . unwrap () ; let payload_limit = Some ( MAX_DATA_STORE_SIZE ) . : Builder :: new () . name ( " fc_api_test " . to_owned () ) . spawn ( move || { ApiServer :: new ( mmds_info api_request_sender vmm_response_receiver to_vmm_fd ) . bind_and_run ( PathBuf :: from ( api_thread_path_to_socket ) time_reporter seccomp_filters . get ( " api " ) . unwrap () payload_limit ) . unwrap () ; } ) . unwrap () . : sleep ( Duration :: from_millis ( 10 )) ; to_api . send ( Box :: new ( Ok ( VmmData :: InstanceInformation ( InstanceInfo :: default () )))) . unwrap () ; let mut sock = UnixStream :: connect ( PathBuf :: from ( path_to_socket )) . unwrap () ; Send a GET instance - info request .