kkcloud_framework/
ctrl.rs

1//!
2//! # Resource Controller
3//!
4//! All resoures are under this moduler's management.
5//!
6
7use crate::{
8    err::*,
9    model::{Env, EnvId, User, UserId, Vm, VmEngine, VmId, VmTemplate},
10};
11use lazy_static::lazy_static;
12use parking_lot::RwLock;
13use ruc::{err::*, *};
14use std::{
15    collections::{HashMap, HashSet},
16    ops::Deref,
17    sync::Arc,
18};
19
20lazy_static! {
21    /// Global entrypoint.
22    pub static ref SERV: ServCtrl = Arc::new(Service::default());
23    /// Collections of vm-engines, can NOT be changed in runtime.
24    pub static ref ENGINE: EngineCtrl = pnk!(EngineCtrl::init(None));
25    /// Collections of vm-templates, can be updated in runtime.
26    pub static ref TEMPLATE: TemplateCtrl = TemplateCtrl::default();
27}
28
29type ServCtrl = Arc<Service>;
30
31/// Service is a global data collection.
32#[derive(Default)]
33pub struct Service {
34    #[allow(missing_docs)]
35    pub all_user: Arc<RwLock<HashMap<UserId, User>>>,
36    #[allow(missing_docs)]
37    pub all_env: Arc<RwLock<HashMap<EnvId, Env>>>,
38    #[allow(missing_docs)]
39    pub all_vm: Arc<RwLock<HashMap<VmId, Vm>>>,
40}
41
42/// {Vm Engine Name} => {Vm Engine Object}
43#[derive(Clone)]
44pub struct EngineCtrl(Arc<HashMap<String, Arc<dyn VmEngine>>>);
45
46impl EngineCtrl {
47    /// Caller(user) uses this function to init [ENGINES](self::ENGINES).
48    pub fn init(em: Option<Vec<Arc<dyn VmEngine>>>) -> Option<EngineCtrl> {
49        static mut EM: Option<EngineCtrl> = None;
50
51        unsafe {
52            if let Some(e) = EM.as_ref() {
53                Some(e.clone())
54            } else if let Some(e) = em {
55                let ret = EngineCtrl(Arc::new(
56                    e.into_iter().map(|ve| (ve.name().to_owned(), ve)).collect(),
57                ));
58                EM = Some(ret.clone());
59                Some(ret)
60            } else {
61                None
62            }
63        }
64    }
65}
66
67impl Deref for EngineCtrl {
68    type Target = Arc<HashMap<String, Arc<dyn VmEngine>>>;
69    fn deref(&self) -> &Self::Target {
70        &self.0
71    }
72}
73
74/// The container of vm templates,
75/// {Vm Template Name} => {Vm Template Object}
76#[derive(Default)]
77pub struct TemplateCtrl(Arc<RwLock<HashMap<String, VmTemplate>>>);
78
79impl TemplateCtrl {
80    /// Replace the whole data with a new one.
81    #[inline(always)]
82    pub fn reinit(&mut self, t: HashMap<String, VmTemplate>) {
83        *self.0.write() = t;
84    }
85
86    /// Add all given elements to current data.
87    #[inline(always)]
88    pub fn add(&mut self, t: HashMap<String, VmTemplate>) {
89        let mut ts = self.0.write();
90        t.into_iter().for_each(|(k, v)| {
91            ts.insert(k, v);
92        })
93    }
94
95    /// Similar to `add`, but ensure none of existing templetes will be replaced.
96    #[inline(always)]
97    pub fn add_safe(&mut self, t: HashMap<String, VmTemplate>) -> Result<()> {
98        if self.0.read().keys().any(|k| t.get(k).is_some()) {
99            return Err(e!(ERR_KK_CTRL_UPDATE_TEMPLATE).into());
100        }
101        self.add(t);
102        Ok(())
103    }
104
105    /// Delete all given templates from current data.
106    #[inline(always)]
107    pub fn del(&mut self, t: HashSet<String>) {
108        let mut ts = self.0.write();
109        t.iter().for_each(|t| {
110            ts.remove(t);
111        })
112    }
113}
114
115impl Deref for TemplateCtrl {
116    type Target = Arc<RwLock<HashMap<String, VmTemplate>>>;
117    fn deref(&self) -> &Self::Target {
118        &self.0
119    }
120}