From e6c3b4e063b225256e822ded4d0171eb5fc34dde Mon Sep 17 00:00:00 2001 From: kieran Date: Tue, 26 Nov 2024 15:11:12 +0000 Subject: [PATCH] feat: readonly mode --- config.yaml | 1 + src/api.rs | 23 +++++++++++++---------- src/bin/api.rs | 3 ++- src/lib.rs | 2 +- src/status.rs | 2 +- src/worker.rs | 16 +++++++++++++--- 6 files changed, 31 insertions(+), 16 deletions(-) diff --git a/config.yaml b/config.yaml index 46ee591..b7f3ce3 100644 --- a/config.yaml +++ b/config.yaml @@ -1,5 +1,6 @@ # MySQL database connection string db: "mysql://root:root@localhost:3376/lnvps" +read_only: true lnd: url: "https://127.0.0.1:10003" cert: "/home/kieran/.polar/networks/2/volumes/lnd/alice/tls.cert" diff --git a/src/api.rs b/src/api.rs index 00fa3be..03de2fe 100644 --- a/src/api.rs +++ b/src/api.rs @@ -69,7 +69,11 @@ struct ApiVmStatus { } #[get("/api/v1/vm")] -async fn v1_list_vms(auth: Nip98Auth, db: &State>, vm_state: &State) -> ApiResult> { +async fn v1_list_vms( + auth: Nip98Auth, + db: &State>, + vm_state: &State, +) -> ApiResult> { let pubkey = auth.event.pubkey.to_bytes(); let uid = db.upsert_user(&pubkey).await?; let mut vms = db.list_user_vms(uid).await?; @@ -81,17 +85,19 @@ async fn v1_list_vms(auth: Nip98Auth, db: &State>, vm_state: &S } let state = vm_state.get_state(vm.id).await; - ret.push(ApiVmStatus { - vm, - status: state, - }); + ret.push(ApiVmStatus { vm, status: state }); } ApiData::ok(ret) } #[get("/api/v1/vm/")] -async fn v1_get_vm(auth: Nip98Auth, db: &State>, vm_state: &State, id: u64) -> ApiResult { +async fn v1_get_vm( + auth: Nip98Auth, + db: &State>, + vm_state: &State, + id: u64, +) -> ApiResult { let pubkey = auth.event.pubkey.to_bytes(); let uid = db.upsert_user(&pubkey).await?; let mut vm = db.get_vm(id).await?; @@ -103,10 +109,7 @@ async fn v1_get_vm(auth: Nip98Auth, db: &State>, vm_state: &Sta t.hydrate_up(db).await?; } let state = vm_state.get_state(vm.id).await; - ApiData::ok(ApiVmStatus { - vm, - status: state, - }) + ApiData::ok(ApiVmStatus { vm, status: state }) } #[get("/api/v1/image")] diff --git a/src/bin/api.rs b/src/bin/api.rs index 86b74b7..5bfdaff 100644 --- a/src/bin/api.rs +++ b/src/bin/api.rs @@ -18,6 +18,7 @@ use std::time::Duration; pub struct Settings { pub db: String, pub lnd: LndConfig, + pub read_only: bool, } #[derive(Debug, Deserialize, Serialize)] @@ -49,7 +50,7 @@ async fn main() -> Result<(), Error> { } let status = VmStateCache::new(); - let mut worker = Worker::new(db.clone(), lnd.clone(), status.clone()); + let mut worker = Worker::new(config.read_only, db.clone(), lnd.clone(), status.clone()); let sender = worker.sender(); tokio::spawn(async move { loop { diff --git a/src/lib.rs b/src/lib.rs index a12a2df..ad2b008 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -4,5 +4,5 @@ pub mod host; pub mod invoice; pub mod nip98; pub mod provisioner; -pub mod worker; pub mod status; +pub mod worker; diff --git a/src/status.rs b/src/status.rs index 60df68c..1c1f707 100644 --- a/src/status.rs +++ b/src/status.rs @@ -49,4 +49,4 @@ impl VmStateCache { let guard = self.state.read().await; guard.get(&id).cloned().unwrap_or_default() } -} \ No newline at end of file +} diff --git a/src/worker.rs b/src/worker.rs index e786bd3..ad0e562 100644 --- a/src/worker.rs +++ b/src/worker.rs @@ -19,6 +19,7 @@ pub enum WorkJob { } pub struct Worker { + read_only: bool, db: Box, lnd: Client, provisioner: Box, @@ -28,10 +29,16 @@ pub struct Worker { } impl Worker { - pub fn new(db: D, lnd: Client, vm_state_cache: VmStateCache) -> Self { + pub fn new( + read_only: bool, + db: D, + lnd: Client, + vm_state_cache: VmStateCache, + ) -> Self { let (tx, rx) = unbounded_channel(); let p = LNVpsProvisioner::new(db.clone(), lnd.clone()); Self { + read_only, db: Box::new(db), provisioner: Box::new(p), vm_state_cache, @@ -47,6 +54,9 @@ impl Worker { /// Spawn a VM on the host async fn spawn_vm(&self, vm: &Vm, vm_host: &VmHost, client: &ProxmoxClient) -> Result<()> { + if self.read_only { + bail!("Cant spawn VM's in read-only mode"); + } let mut ips = self.db.get_vm_ip_assignments(vm.id).await?; if ips.is_empty() { ips = self.provisioner.allocate_ips(vm.id).await?; @@ -113,7 +123,7 @@ impl Worker { let state = VmState { state: match s.status { VmStatus::Stopped => VmRunningState::Stopped, - VmStatus::Running => VmRunningState::Running + VmStatus::Running => VmRunningState::Running, }, cpu_usage: s.cpu.unwrap_or(0.0), mem_usage: s.mem.unwrap_or(0) as f32 / s.max_mem.unwrap_or(1) as f32, @@ -138,7 +148,7 @@ impl Worker { match job { WorkJob::CheckVm { vm_id } => { if let Err(e) = self.check_vm(vm_id).await { - error!("Failed to check VM {}: {:?}", vm_id, e); + error!("Failed to check VM {}: {}", vm_id, e); } } WorkJob::SendNotification { .. } => {}