Files
komodo/bin/core/src/helpers/stack/mod.rs
Maxwell Becker 5fc0a87dea 1.14 - Rename to Komodo - Docker Management (#56)
* setup network page

* add Network, Image, Container

* Docker ListItems and Inspects

* frontend build

* dev0

* network info working

* fix cargo lock

* dev1

* pages for the things

* implement Active in dashboard

* RunBuild update trigger list refresh

* rename deployment executions to StartDeployment etc

* add server level container control

* dev2

* add Config field to Image

* can get image labels from Config.Labels

* mount container page

* server show resource count

* add GetContainerLog api

* add _AllContainers api

* dev3

* move ResourceTarget to entities mod

* GetResourceMatchingContainer api

* connect container to resource

* dev4 add volume names to container list items

* ts types

* volume / image / network unused management

* add image history to image page

* fix PruneContainers incorret Operation

* update cache for server for server after server actions

* dev5

* add singapore to Hetzner

* implement delete single network / image / volume api

* dev6

* include "in use" on Docker Lists

* add docker resource delete buttons

* is nice

* fix volume all in use

* remove google font dependency

* use host networking in test compose

* implement Secret Variables (hidden in logs)

* remove unneeded borrow

* interpolate variables / secrets into extra args / onclone / onpull / command etc

* validate empty strings before SelectItem

* rename everything to Komodo

* rename workspace to komodo

* rc1
2024-09-01 15:38:40 -07:00

102 lines
2.3 KiB
Rust

use anyhow::{anyhow, Context};
use async_timing_util::{wait_until_timelength, Timelength};
use komodo_client::{
api::write::RefreshStackCache,
entities::{
permission::PermissionLevel,
server::{Server, ServerState},
stack::Stack,
user::{stack_user, User},
},
};
use mungos::find::find_collect;
use regex::Regex;
use resolver_api::Resolve;
use crate::{
config::core_config,
resource,
state::{db_client, State},
};
use super::query::get_server_with_state;
pub mod execute;
pub mod remote;
pub mod services;
pub fn spawn_stack_refresh_loop() {
let interval: Timelength = core_config()
.stack_poll_interval
.try_into()
.expect("Invalid stack poll interval");
tokio::spawn(async move {
refresh_stacks().await;
loop {
wait_until_timelength(interval, 3000).await;
refresh_stacks().await;
}
});
}
async fn refresh_stacks() {
let Ok(stacks) =
find_collect(&db_client().await.stacks, None, None)
.await
.inspect_err(|e| {
warn!("failed to get stacks from db in refresh task | {e:#}")
})
else {
return;
};
for stack in stacks {
State
.resolve(
RefreshStackCache { stack: stack.id },
stack_user().clone(),
)
.await
.inspect_err(|e| {
warn!("failed to refresh stack cache in refresh task | stack: {} | {e:#}", stack.name)
})
.ok();
}
}
pub async fn get_stack_and_server(
stack: &str,
user: &User,
permission_level: PermissionLevel,
block_if_server_unreachable: bool,
) -> anyhow::Result<(Stack, Server)> {
let stack = resource::get_check_permissions::<Stack>(
stack,
user,
permission_level,
)
.await?;
if stack.config.server_id.is_empty() {
return Err(anyhow!("Stack has no server configured"));
}
let (server, status) =
get_server_with_state(&stack.config.server_id).await?;
if block_if_server_unreachable && status != ServerState::Ok {
return Err(anyhow!(
"cannot send action when server is unreachable or disabled"
));
}
Ok((stack, server))
}
pub fn compose_container_match_regex(
container_name: &str,
) -> anyhow::Result<Regex> {
let regex = format!("^{container_name}-?[0-9]*$");
Regex::new(&regex).with_context(|| {
format!("failed to construct valid regex from {regex}")
})
}